diff --git a/.wmdev.yaml b/.wmdev.yaml index 0707f107f6..376c0229c0 100644 --- a/.wmdev.yaml +++ b/.wmdev.yaml @@ -73,3 +73,7 @@ profiles: 3) Upload to asciinema.org: XDG_DATA_HOME=/tmp/.local/share \ asciinema upload --server-url https://asciinema.org /tmp/demo.cast + +linkedRepos: + - repo: windmill-labs/windmill-ee-private + alias: ee \ No newline at end of file diff --git a/.workmux.yaml b/.workmux.yaml index ec97aad3cf..c4adfdb991 100644 --- a/.workmux.yaml +++ b/.workmux.yaml @@ -11,7 +11,7 @@ worktree_prefix: "" window_prefix: "wm-" auto_name: - model: "claude-sonnet-4.6" + model: "gemini-2.5-flash-lite" system_prompt: | Generate a concise git branch name based on the task description. diff --git a/README_WORKMUX_DEV.md b/README_WORKMUX_DEV.md index bfb2d7e576..0b113e47ee 100644 --- a/README_WORKMUX_DEV.md +++ b/README_WORKMUX_DEV.md @@ -65,7 +65,7 @@ Setting up zsh autocomplete is also recommended — see the [workmux docs](https Each worktree is assigned a **slot** that determines its ports: | Slot | Backend | Frontend | -|------|---------|----------| +| ---- | ------- | -------- | | 0 | 8000 | 3000 | | 1 | 8010 | 3010 | | 2 | 8020 | 3020 | @@ -192,7 +192,6 @@ sandbox: This mounts both the main EE repo (used by the main worktree) and the EE worktrees directory (used by feature worktrees) into every sandbox container. - ## Cursor SSH Integration (`wmc`) `wm-cursor` (aliased as `wmc`) gives each worktree its own Cursor SSH remote window with an independently-focused tmux session. All windows are visible in the status bar across all Cursor terminals, but each one is focused on its own worktree. @@ -219,6 +218,7 @@ This: 1. **Merges `.vscode/settings.json`** — adds the `wm-tmux` terminal profile (auto-attaches to the `main` tmux session), disables auto port forwarding, configures forwarding for ports 8000/3000/5432, and stops rust-analyzer from auto-starting. Existing settings are preserved. 2. **Creates `.vscode/tasks.json`** — auto-starts the dev database (`start-dev-db.sh`) when the folder opens. 3. **Adds `wmc` alias to `~/.zshrc`** — so you can use `wmc` from any tmux window. +4. **Adds `eval "$(wmc completions)"`** to `~/.zshrc` — provides tab-completion for subcommands and worktree names (for `open`, `open-ee`, and `close`). After setup, reopen Cursor's terminal to pick up the new profile. @@ -240,6 +240,14 @@ This runs `workmux add`, creates a grouped tmux session, writes `.vscode/setting wmc open my-feature ``` +**Open the EE worktree in Cursor (no tmux session):** + +```bash +wmc open-ee my-feature +``` + +This finds the matching `windmill-ee-private__worktrees/` directory and opens it in a new Cursor window. + **Close a worktree's Cursor window and tmux window (keeps the worktree):** ```bash diff --git a/backend/.sqlx/query-02e526146f3584cd599dec708e1be48db3b0cd1c74adbfa2e4039377daa016f0.json b/backend/.sqlx/query-02e526146f3584cd599dec708e1be48db3b0cd1c74adbfa2e4039377daa016f0.json index 027ef3464f..5ca75fe782 100644 --- a/backend/.sqlx/query-02e526146f3584cd599dec708e1be48db3b0cd1c74adbfa2e4039377daa016f0.json +++ b/backend/.sqlx/query-02e526146f3584cd599dec708e1be48db3b0cd1c74adbfa2e4039377daa016f0.json @@ -20,7 +20,8 @@ "resource", "variable", "ducklake", - "datatable" + "datatable", + "volume" ] } } diff --git a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json index d29a18c691..e7ed0aee65 100644 --- a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json +++ b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json @@ -46,11 +46,11 @@ ] }, "nullable": [ - true, - true, - true, - true, - true, + false, + false, + false, + false, + false, true, true ] diff --git a/backend/.sqlx/query-7e4aa6b19b110bca423b3a3f428826d92b9808c64ef989fef2142bc8e02d6630.json b/backend/.sqlx/query-7e4aa6b19b110bca423b3a3f428826d92b9808c64ef989fef2142bc8e02d6630.json deleted file mode 100644 index 37c73fbbc3..0000000000 --- a/backend/.sqlx/query-7e4aa6b19b110bca423b3a3f428826d92b9808c64ef989fef2142bc8e02d6630.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO token (token, email, label, expiration, scopes, workspace_id)\n VALUES ($1, $2, $3, now() + ($4 || ' seconds')::interval, $5, $6)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Varchar", - "Varchar", - "Text", - "TextArray", - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "7e4aa6b19b110bca423b3a3f428826d92b9808c64ef989fef2142bc8e02d6630" -} diff --git a/backend/.sqlx/query-0ef37117c369f03236e18f9dbb1f3d52776c8cb73f2507199c6ca16d4d2405ba.json b/backend/.sqlx/query-886a921adc115f0a9c6f3a68381bd8f5a16866135120175d9073b9b2c41bbd51.json similarity index 58% rename from backend/.sqlx/query-0ef37117c369f03236e18f9dbb1f3d52776c8cb73f2507199c6ca16d4d2405ba.json rename to backend/.sqlx/query-886a921adc115f0a9c6f3a68381bd8f5a16866135120175d9073b9b2c41bbd51.json index 1394ed76a4..b43b6790ad 100644 --- a/backend/.sqlx/query-0ef37117c369f03236e18f9dbb1f3d52776c8cb73f2507199c6ca16d4d2405ba.json +++ b/backend/.sqlx/query-886a921adc115f0a9c6f3a68381bd8f5a16866135120175d9073b9b2c41bbd51.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT email FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%', $2::text)) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )", + "query": "SELECT email FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%@', $2::text)) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )", "describe": { "columns": [ { @@ -19,5 +19,5 @@ false ] }, - "hash": "0ef37117c369f03236e18f9dbb1f3d52776c8cb73f2507199c6ca16d4d2405ba" + "hash": "886a921adc115f0a9c6f3a68381bd8f5a16866135120175d9073b9b2c41bbd51" } diff --git a/backend/.sqlx/query-a9e29764b5b9d94269e2b8aa755c71b61774c8ff8ae218d7a8d6ed0ac0169366.json b/backend/.sqlx/query-a9e29764b5b9d94269e2b8aa755c71b61774c8ff8ae218d7a8d6ed0ac0169366.json index b39c1b5b31..ef3968cdfa 100644 --- a/backend/.sqlx/query-a9e29764b5b9d94269e2b8aa755c71b61774c8ff8ae218d7a8d6ed0ac0169366.json +++ b/backend/.sqlx/query-a9e29764b5b9d94269e2b8aa755c71b61774c8ff8ae218d7a8d6ed0ac0169366.json @@ -16,7 +16,8 @@ "resource", "variable", "ducklake", - "datatable" + "datatable", + "volume" ] } } diff --git a/backend/.sqlx/query-2e1d1c59bfc53d58962251822c85cf9a26e3b2888702e5e9d5fc1b082901df09.json b/backend/.sqlx/query-c0fad64e5d707ffa29d236f558e23b608168dc3a1b3857d2ad33ec20627acbff.json similarity index 59% rename from backend/.sqlx/query-2e1d1c59bfc53d58962251822c85cf9a26e3b2888702e5e9d5fc1b082901df09.json rename to backend/.sqlx/query-c0fad64e5d707ffa29d236f558e23b608168dc3a1b3857d2ad33ec20627acbff.json index 6bbccc1fae..7a682d9fbd 100644 --- a/backend/.sqlx/query-2e1d1c59bfc53d58962251822c85cf9a26e3b2888702e5e9d5fc1b082901df09.json +++ b/backend/.sqlx/query-c0fad64e5d707ffa29d236f558e23b608168dc3a1b3857d2ad33ec20627acbff.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_invite\n (workspace_id, email, is_admin, operator)\n SELECT $1::text, email, false, $3 FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%', $2::text)) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )\n ON CONFLICT DO NOTHING", + "query": "INSERT INTO workspace_invite\n (workspace_id, email, is_admin, operator)\n SELECT $1::text, email, false, $3 FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%@', $2::text)) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )\n ON CONFLICT DO NOTHING", "describe": { "columns": [], "parameters": { @@ -12,5 +12,5 @@ }, "nullable": [] }, - "hash": "2e1d1c59bfc53d58962251822c85cf9a26e3b2888702e5e9d5fc1b082901df09" + "hash": "c0fad64e5d707ffa29d236f558e23b608168dc3a1b3857d2ad33ec20627acbff" } diff --git a/backend/.sqlx/query-c624f15f3e321b1eecf123da9bf0b18e8c1d16ef25ffb9d04e5447d0d583d55c.json b/backend/.sqlx/query-c624f15f3e321b1eecf123da9bf0b18e8c1d16ef25ffb9d04e5447d0d583d55c.json deleted file mode 100644 index edb2fc7f49..0000000000 --- a/backend/.sqlx/query-c624f15f3e321b1eecf123da9bf0b18e8c1d16ef25ffb9d04e5447d0d583d55c.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO token\n (token, email, label, expiration, super_admin, scopes, workspace_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Varchar", - "Varchar", - "Timestamptz", - "Bool", - "TextArray", - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "c624f15f3e321b1eecf123da9bf0b18e8c1d16ef25ffb9d04e5447d0d583d55c" -} diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index b703992dff..2cde798d1e 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -a4546264d41ce7122dfd127f4b17f724eb63c40a +2fb7884849a563bae023574baa2d55fa1fab1176 diff --git a/backend/migrations/20260225000000_custom_instance_user_replication.down.sql b/backend/migrations/20260225000000_custom_instance_user_replication.down.sql new file mode 100644 index 0000000000..bd8b648579 --- /dev/null +++ b/backend/migrations/20260225000000_custom_instance_user_replication.down.sql @@ -0,0 +1,10 @@ +DO $$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'custom_instance_user') THEN + ALTER ROLE custom_instance_user NOREPLICATION; + END IF; +EXCEPTION + WHEN others THEN + RAISE NOTICE 'Error revoking REPLICATION from custom_instance_user: %', SQLERRM; +END +$$; diff --git a/backend/migrations/20260225000000_custom_instance_user_replication.up.sql b/backend/migrations/20260225000000_custom_instance_user_replication.up.sql new file mode 100644 index 0000000000..146cdf6afe --- /dev/null +++ b/backend/migrations/20260225000000_custom_instance_user_replication.up.sql @@ -0,0 +1,10 @@ +DO $$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'custom_instance_user') THEN + ALTER ROLE custom_instance_user REPLICATION; + END IF; +EXCEPTION + WHEN others THEN + RAISE NOTICE 'Error granting REPLICATION to custom_instance_user: %', SQLERRM; +END +$$; diff --git a/backend/migrations/20260225100000_asset_covering_index.down.sql b/backend/migrations/20260225100000_asset_covering_index.down.sql new file mode 100644 index 0000000000..12f1b56303 --- /dev/null +++ b/backend/migrations/20260225100000_asset_covering_index.down.sql @@ -0,0 +1,5 @@ +DROP INDEX IF EXISTS idx_asset_ws_path_kind_recent; + +-- Restore the dropped indexes +CREATE INDEX IF NOT EXISTS idx_asset_workspace_created_id ON asset (workspace_id, created_at DESC, id DESC); +CREATE INDEX IF NOT EXISTS idx_asset_kind_path ON asset (workspace_id, kind, path); diff --git a/backend/migrations/20260225100000_asset_covering_index.up.sql b/backend/migrations/20260225100000_asset_covering_index.up.sql new file mode 100644 index 0000000000..e2d4ea10a8 --- /dev/null +++ b/backend/migrations/20260225100000_asset_covering_index.up.sql @@ -0,0 +1,11 @@ +-- Covering index for the list_assets CTE: GROUP BY (path, kind) + MAX(created_at, id) + ORDER BY +-- Includes usage_kind and usage_path to allow full index-only scan (avoiding heap lookups for filter conditions) +CREATE INDEX IF NOT EXISTS idx_asset_ws_path_kind_recent + ON asset (workspace_id, path, kind, created_at DESC, id DESC) + INCLUDE (usage_kind, usage_path); + +-- Drop indexes now subsumed by idx_asset_ws_path_kind_recent: +-- idx_asset_workspace_created_id (workspace_id, created_at DESC, id DESC) - only used by list_assets CTE +-- idx_asset_kind_path (workspace_id, kind, path) - only used by list_assets CTE/outer join, covered by new index + PK +DROP INDEX IF EXISTS idx_asset_workspace_created_id; +DROP INDEX IF EXISTS idx_asset_kind_path; diff --git a/backend/windmill-api-assets/src/lib.rs b/backend/windmill-api-assets/src/lib.rs index 48817cfdd1..d1dfde41e0 100644 --- a/backend/windmill-api-assets/src/lib.rs +++ b/backend/windmill-api-assets/src/lib.rs @@ -144,7 +144,7 @@ async fn list_assets( format!( r#"FROM asset LEFT JOIN v2_job job_cte ON asset.usage_kind = 'job' - AND asset.usage_path = job_cte.id::text + AND job_cte.id = CASE WHEN asset.usage_kind = 'job' THEN asset.usage_path::uuid END AND job_cte.workspace_id = $1"# ) } else { @@ -209,7 +209,7 @@ async fn list_assets( ) = resource.path AND resource.workspace_id = $1 LEFT JOIN v2_job job ON asset.usage_kind = 'job' - AND asset.usage_path = job.id::text + AND job.id = CASE WHEN asset.usage_kind = 'job' THEN asset.usage_path::uuid END AND job.workspace_id = $1 WHERE asset.workspace_id = $1 AND (asset.kind <> 'resource' OR resource.path IS NOT NULL) diff --git a/backend/windmill-api-settings/src/lib.rs b/backend/windmill-api-settings/src/lib.rs index a58a760372..04a1eb617b 100644 --- a/backend/windmill-api-settings/src/lib.rs +++ b/backend/windmill-api-settings/src/lib.rs @@ -12,24 +12,24 @@ use std::{collections::HashMap, time::Duration}; mod ee; pub mod ee_oss; -use windmill_api_auth::{require_super_admin, ApiAuthed}; #[cfg(feature = "enterprise")] use windmill_api_auth::require_devops_role; +use windmill_api_auth::{require_super_admin, ApiAuthed}; use windmill_common::utils::HTTP_CLIENT_PERMISSIVE as HTTP_CLIENT; use windmill_common::DB; use ee_oss::validate_license_key; use windmill_common::usernames::generate_instance_username_for_all_users; -use axum::{ - extract::{Extension, Path}, - routing::{get, post}, - body::Body, - response::Response, - Json, Router, -}; #[cfg(feature = "enterprise")] use axum::extract::Query; +use axum::{ + body::Body, + extract::{Extension, Path}, + response::Response, + routing::{get, post}, + Json, Router, +}; use serde_json::json; use serde::{Deserialize, Serialize}; @@ -43,9 +43,8 @@ use windmill_common::{ get_database_url, global_settings::{ APP_WORKSPACED_ROUTE_SETTING, AUTOMATE_USERNAME_CREATION_SETTING, - CRITICAL_ALERT_MUTE_UI_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, - EMAIL_DOMAIN_SETTING, ENV_SETTINGS, HUB_ACCESSIBLE_URL_SETTING, - HUB_BASE_URL_SETTING, + CRITICAL_ALERT_MUTE_UI_SETTING, DEFAULT_TAGS_WORKSPACES_SETTING, EMAIL_DOMAIN_SETTING, + ENV_SETTINGS, HUB_ACCESSIBLE_URL_SETTING, HUB_BASE_URL_SETTING, }, instance_config::{self, ApplyMode, InstanceConfig}, server::Smtp, @@ -171,7 +170,9 @@ pub async fn test_s3_bucket( .await? .store; - let mut list = client.list(Some(&windmill_object_store::object_store_reexports::Path::from("".to_string()))); + let mut list = client.list(Some( + &windmill_object_store::object_store_reexports::Path::from("".to_string()), + )); let first_file = list.next().await; if first_file.is_some() { if let Err(e) = first_file.as_ref().unwrap() { @@ -189,7 +190,10 @@ pub async fn test_s3_bucket( )); tracing::info!("Testing blob storage at path: {path}"); client - .put(&path, windmill_object_store::object_store_reexports::PutPayload::from_static(b"hello")) + .put( + &path, + windmill_object_store::object_store_reexports::PutPayload::from_static(b"hello"), + ) .await .map_err(|e| anyhow::anyhow!("error writing file to {path}: {e:#}"))?; let content = client @@ -290,17 +294,17 @@ pub async fn set_global_setting_internal( match value { serde_json::Value::Null => { if instance_config::PROTECTED_SETTINGS.contains(&key.as_str()) { - return Err(error::Error::BadRequest( - format!("{key} is a protected setting and cannot be deleted"), - )); + return Err(error::Error::BadRequest(format!( + "{key} is a protected setting and cannot be deleted" + ))); } delete_global_setting(db, &key).await?; } serde_json::Value::String(x) if x.is_empty() => { if instance_config::PROTECTED_SETTINGS.contains(&key.as_str()) { - return Err(error::Error::BadRequest( - format!("{key} is a protected setting and cannot be set to empty"), - )); + return Err(error::Error::BadRequest(format!( + "{key} is a protected setting and cannot be set to empty" + ))); } delete_global_setting(db, &key).await?; } @@ -437,7 +441,8 @@ async fn get_instance_config_yaml( let config = InstanceConfig::from_db(&db) .await .map_err(|e| error::Error::internal_err(e.to_string()))?; - let yaml = config.to_sorted_yaml() + let yaml = config + .to_sorted_yaml() .map_err(|e| error::Error::internal_err(e))?; Response::builder() .header("content-type", "application/yaml") @@ -478,8 +483,7 @@ async fn set_instance_config( .map(|(k, v)| { ( k.clone(), - serde_json::to_value(v) - .expect("WorkerGroupConfig serialization cannot fail"), + serde_json::to_value(v).expect("WorkerGroupConfig serialization cannot fail"), ) }) .collect(); @@ -489,8 +493,7 @@ async fn set_instance_config( .map(|(k, v)| { ( k.clone(), - serde_json::to_value(v) - .expect("WorkerGroupConfig serialization cannot fail"), + serde_json::to_value(v).expect("WorkerGroupConfig serialization cannot fail"), ) }) .collect(); @@ -944,7 +947,8 @@ async fn setup_custom_instance_pg_database_inner( GRANT CREATE ON DATABASE \"{dbname}\" TO custom_instance_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO custom_instance_user; - ALTER ROLE custom_instance_user CREATEROLE;" + ALTER ROLE custom_instance_user CREATEROLE; + ALTER ROLE custom_instance_user REPLICATION;" )) .await .map_err(|e| { @@ -1083,19 +1087,16 @@ async fn sync_cached_resource_types( use windmill_common::worker::HUB_RT_CACHE_DIR; let cache_path = format!("{}/resource_types.json", HUB_RT_CACHE_DIR); - let content = tokio::fs::read_to_string(&cache_path) - .await - .map_err(|e| { - error::Error::NotFound(format!( - "No cached resource types found at {}: {}", - cache_path, e - )) - })?; + let content = tokio::fs::read_to_string(&cache_path).await.map_err(|e| { + error::Error::NotFound(format!( + "No cached resource types found at {}: {}", + cache_path, e + )) + })?; - let cached_types: Vec = - serde_json::from_str(&content).map_err(|e| { - error::Error::InternalErr(format!("Failed to parse cached resource types: {}", e)) - })?; + let cached_types: Vec = serde_json::from_str(&content).map_err(|e| { + error::Error::InternalErr(format!("Failed to parse cached resource types: {}", e)) + })?; let mut synced_count = 0; @@ -1176,7 +1177,10 @@ mod tests { deserialized.global_settings.base_url.as_deref(), Some("https://windmill.example.com") ); - assert_eq!(deserialized.global_settings.retention_period_secs, Some(86400)); + assert_eq!( + deserialized.global_settings.retention_period_secs, + Some(86400) + ); assert_eq!(deserialized.global_settings.expose_metrics, Some(true)); let wc = &deserialized.worker_configs["default"]; assert_eq!( @@ -1208,9 +1212,7 @@ mod tests { let retention_pos = yaml.find("retention_period_secs:").unwrap(); assert!( - base_url_pos < email_pos - && email_pos < expose_pos - && expose_pos < retention_pos, + base_url_pos < email_pos && email_pos < expose_pos && expose_pos < retention_pos, "global_settings keys should be alphabetically sorted, got yaml:\n{yaml}" ); } @@ -1220,22 +1222,34 @@ mod tests { let config = InstanceConfig { global_settings: GlobalSettings::default(), worker_configs: BTreeMap::from([ - ("gpu".to_string(), WorkerGroupConfig { - init_bash: Some("echo gpu".to_string()), - ..Default::default() - }), - ("native".to_string(), WorkerGroupConfig { - init_bash: Some("echo native".to_string()), - ..Default::default() - }), - ("default".to_string(), WorkerGroupConfig { - init_bash: Some("echo default".to_string()), - ..Default::default() - }), - ("alpha".to_string(), WorkerGroupConfig { - init_bash: Some("echo alpha".to_string()), - ..Default::default() - }), + ( + "gpu".to_string(), + WorkerGroupConfig { + init_bash: Some("echo gpu".to_string()), + ..Default::default() + }, + ), + ( + "native".to_string(), + WorkerGroupConfig { + init_bash: Some("echo native".to_string()), + ..Default::default() + }, + ), + ( + "default".to_string(), + WorkerGroupConfig { + init_bash: Some("echo default".to_string()), + ..Default::default() + }, + ), + ( + "alpha".to_string(), + WorkerGroupConfig { + init_bash: Some("echo alpha".to_string()), + ..Default::default() + }, + ), ]), }; @@ -1264,26 +1278,40 @@ mod tests { ..Default::default() }, worker_configs: BTreeMap::from([ - ("default".to_string(), WorkerGroupConfig { - worker_tags: Some(vec!["deno".to_string()]), - ..Default::default() - }), - ("native".to_string(), WorkerGroupConfig { - init_bash: Some("echo hi".to_string()), - ..Default::default() - }), + ( + "default".to_string(), + WorkerGroupConfig { + worker_tags: Some(vec!["deno".to_string()]), + ..Default::default() + }, + ), + ( + "native".to_string(), + WorkerGroupConfig { + init_bash: Some("echo hi".to_string()), + ..Default::default() + }, + ), ]), }; let yaml = config.to_sorted_yaml().unwrap(); let deserialized: InstanceConfig = serde_yml::from_str(&yaml).unwrap(); - assert_eq!(deserialized.global_settings.base_url.as_deref(), Some("https://rt.test")); - assert_eq!(deserialized.global_settings.retention_period_secs, Some(7200)); + assert_eq!( + deserialized.global_settings.base_url.as_deref(), + Some("https://rt.test") + ); + assert_eq!( + deserialized.global_settings.retention_period_secs, + Some(7200) + ); assert_eq!(deserialized.global_settings.expose_metrics, Some(false)); assert_eq!(deserialized.worker_configs.len(), 2); assert_eq!( - deserialized.worker_configs["default"].worker_tags.as_deref(), + deserialized.worker_configs["default"] + .worker_tags + .as_deref(), Some(["deno".to_string()].as_slice()) ); assert_eq!( diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index c958a4c03c..c18a1fbf11 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -10680,6 +10680,16 @@ paths: required: false schema: type: string + - name: resume_button_text + in: query + required: false + schema: + type: string + - name: cancel_button_text + in: query + required: false + schema: + type: string responses: "200": description: Interactive slack approval message sent successfully @@ -10726,6 +10736,16 @@ paths: required: false schema: type: string + - name: resume_button_text + in: query + required: false + schema: + type: string + - name: cancel_button_text + in: query + required: false + schema: + type: string responses: "200": description: Interactive slack approval message sent successfully diff --git a/backend/windmill-api/src/ai.rs b/backend/windmill-api/src/ai.rs index 20c6d7548b..730df2a875 100644 --- a/backend/windmill-api/src/ai.rs +++ b/backend/windmill-api/src/ai.rs @@ -663,12 +663,30 @@ async fn global_proxy( let base_url = provider.get_base_url(None, &db).await?; - let url = format!("{}/{}", base_url, ai_path); + let is_anthropic = provider.is_anthropic(); + let is_anthropic_sdk = headers.get("X-Anthropic-SDK").is_some(); + + let url = if is_anthropic_sdk { + let truncated_base_url = base_url.trim_end_matches("/v1"); + format!("{}/{}", truncated_base_url, ai_path) + } else { + format!("{}/{}", base_url, ai_path) + }; let mut request = HTTP_CLIENT .request(method, url) .header("content-type", "application/json") - .header("Authorization", format!("Bearer {}", api_key)); + .header("Authorization", format!("Bearer {}", &api_key)); + + if is_anthropic { + request = request.header("X-API-Key", &api_key); + } + + for (header_name, header_value) in headers.iter() { + if header_name.to_string().starts_with("anthropic-") { + request = request.header(header_name, header_value); + } + } // Apply custom headers from AI_HTTP_HEADERS environment variable for (header_name, header_value) in AI_HTTP_HEADERS.iter() { diff --git a/backend/windmill-api/src/approvals.rs b/backend/windmill-api/src/approvals.rs index e2344adc4e..fe9adb602e 100644 --- a/backend/windmill-api/src/approvals.rs +++ b/backend/windmill-api/src/approvals.rs @@ -83,6 +83,12 @@ pub struct QueryDynamicEnumJson { pub dynamic_enums_json: Option, } +#[derive(Deserialize, Debug)] +pub struct QueryButtonText { + pub resume_button_text: Option, + pub cancel_button_text: Option, +} + #[derive(Debug)] pub struct ApprovalFormDetails { pub message_str: String, @@ -266,7 +272,12 @@ pub async fn get_approval_form_details( }) }); - let args_str = args.map_or("None".to_string(), |a| a.get().to_string()); + let args_str = args.map_or("None".to_string(), |a| { + serde_json::from_str::(a.get()) + .ok() + .and_then(|v| serde_json::to_string_pretty(&v).ok()) + .unwrap_or_else(|| a.get().to_string()) + }); let parent_job_id_str = parent_job_id.map_or("None".to_string(), |id| id.to_string()); let script_path_str = script_path.as_deref().unwrap_or("None"); @@ -282,7 +293,7 @@ pub async fn get_approval_form_details( {}: {created_by}\n\n\ {}: {created_at_formatted}\n\n\ {}: {script_path_str}\n\n\ - {}: {args_str}\n\n\ + {}:\n```\n{args_str}\n```\n\n\ {}: {parent_job_id_str}\n\n", bold_format.replace("{}", "Created by"), bold_format.replace("{}", "Created at"), diff --git a/backend/windmill-api/src/db.rs b/backend/windmill-api/src/db.rs index 76cfb7bd3b..1c4b15fea8 100644 --- a/backend/windmill-api/src/db.rs +++ b/backend/windmill-api/src/db.rs @@ -78,6 +78,9 @@ lazy_static::lazy_static! { (20260207000004, include_str!( "../../migrations/20260207000004_concurrent_indexes_other.up.sql" ).replace("CREATE INDEX", "CREATE INDEX CONCURRENTLY").replace("DROP INDEX", "DROP INDEX CONCURRENTLY")), + (20260225100000, include_str!( + "../../migrations/20260225100000_asset_covering_index.up.sql" + ).replace("CREATE INDEX", "CREATE INDEX CONCURRENTLY").replace("DROP INDEX", "DROP INDEX CONCURRENTLY")), ].into_iter().collect(); } diff --git a/backend/windmill-api/src/slack_approvals.rs b/backend/windmill-api/src/slack_approvals.rs index ed6368dada..34a79b4651 100644 --- a/backend/windmill-api/src/slack_approvals.rs +++ b/backend/windmill-api/src/slack_approvals.rs @@ -16,8 +16,8 @@ use crate::jobs::{QueryApprover, ResumeUrls}; use crate::{ approvals::{ extract_w_id_from_resume_url, handle_resume_action, ApprovalFormDetails, FieldType, - MessageFormat, QueryDefaultArgsJson, QueryDynamicEnumJson, QueryFlowStepId, QueryMessage, - ResumeFormField, ResumeSchema, + MessageFormat, QueryButtonText, QueryDefaultArgsJson, QueryDynamicEnumJson, + QueryFlowStepId, QueryMessage, ResumeFormField, ResumeSchema, }, auth::OptTokened, }; @@ -107,6 +107,8 @@ struct ModalActionValue { flow_step_id: Option, default_args_json: Option, dynamic_enums_json: Option, + resume_button_text: Option, + cancel_button_text: Option, } #[derive(Deserialize, Debug)] @@ -200,6 +202,8 @@ pub async fn slack_app_callback_handler( container, default_args_json.as_ref(), dynamic_enums_json.as_ref(), + parsed_value.resume_button_text.as_deref(), + parsed_value.cancel_button_text.as_deref(), ) .await .map_err(|e| Error::BadRequest(e.to_string()))?; @@ -229,6 +233,7 @@ pub async fn request_slack_approval( Query(flow_step_id): Query, Query(default_args_json): Query, Query(dynamic_enums_json): Query, + Query(button_text): Query, ) -> Result { let slack_resource_path = slack_resource_path.slack_resource_path; let channel_id = channel_id.channel_id; @@ -255,6 +260,8 @@ pub async fn request_slack_approval( flow_step_id.as_str(), default_args_json.default_args_json.as_ref(), dynamic_enums_json.dynamic_enums_json.as_ref(), + button_text.resume_button_text.as_deref(), + button_text.cancel_button_text.as_deref(), ) .await .map_err(|e| Error::BadRequest(e.to_string()))?; @@ -752,6 +759,8 @@ async fn send_slack_message( flow_step_id: &str, default_args_json: Option<&serde_json::Value>, dynamic_enums_json: Option<&serde_json::Value>, + resume_button_text: Option<&str>, + cancel_button_text: Option<&str>, ) -> Result> { let url = "https://slack.com/api/chat.postMessage"; @@ -779,6 +788,14 @@ async fn send_slack_message( value["dynamic_enums_json"] = dynamic_enums_json.clone(); } + if let Some(resume_button_text) = resume_button_text { + value["resume_button_text"] = serde_json::json!(resume_button_text); + } + + if let Some(cancel_button_text) = cancel_button_text { + value["cancel_button_text"] = serde_json::json!(cancel_button_text); + } + let payload = serde_json::json!({ "channel": channel_id, "text": "A flow has been suspended. Please approve or reject the flow.", @@ -842,6 +859,8 @@ async fn get_modal_blocks( container: Container, default_args_json: Option<&serde_json::Value>, dynamic_enums_json: Option<&serde_json::Value>, + resume_button_text: Option<&str>, + cancel_button_text: Option<&str>, ) -> Result, Error> { let approval_details = crate::approvals::get_approval_form_details( db, @@ -895,6 +914,8 @@ async fn get_modal_blocks( &urls.resume, resource_path, container, + resume_button_text, + cancel_button_text, ))) } @@ -905,6 +926,8 @@ fn construct_payload( resume_url: &str, resource_path: &str, container: Container, + resume_button_text: Option<&str>, + cancel_button_text: Option<&str>, ) -> serde_json::Value { let mut view = serde_json::json!({ "type": "modal", @@ -912,12 +935,12 @@ fn construct_payload( "notify_on_close": true, "title": { "type": "plain_text", - "text": "Worfklow Suspended" + "text": "Workflow Suspended" }, "blocks": blocks, "submit": { "type": "plain_text", - "text": "Resume Workflow" + "text": resume_button_text.unwrap_or("Resume Workflow") }, "private_metadata": serde_json::json!({ "resume_url": resume_url, "resource_path": resource_path, "container": container, "hide_cancel": hide_cancel }).to_string(), }); @@ -925,7 +948,7 @@ fn construct_payload( if !hide_cancel { view["close"] = serde_json::json!({ "type": "plain_text", - "text": "Cancel Workflow" + "text": cancel_button_text.unwrap_or("Cancel Workflow") }); } @@ -949,6 +972,8 @@ async fn open_modal_with_blocks( container: Container, default_args_json: Option<&serde_json::Value>, dynamic_enums_json: Option<&serde_json::Value>, + resume_button_text: Option<&str>, + cancel_button_text: Option<&str>, ) -> Result<(), Box> { let resume_id = rand::random::(); let blocks_json = match get_modal_blocks( @@ -964,6 +989,8 @@ async fn open_modal_with_blocks( container, default_args_json, dynamic_enums_json, + resume_button_text, + cancel_button_text, ) .await { diff --git a/backend/windmill-duckdb-ffi-internal/Cargo.lock b/backend/windmill-duckdb-ffi-internal/Cargo.lock index 3ae3e5b066..07e428c633 100644 --- a/backend/windmill-duckdb-ffi-internal/Cargo.lock +++ b/backend/windmill-duckdb-ffi-internal/Cargo.lock @@ -14,7 +14,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -27,7 +27,7 @@ checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "const-random", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -35,19 +35,13 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -57,6 +51,15 @@ dependencies = [ "libc", ] +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -107,7 +110,7 @@ dependencies = [ "arrow-schema", "chrono", "half", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "num", ] @@ -230,6 +233,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" @@ -244,9 +253,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bitvec" @@ -262,9 +271,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ "borsh-derive", "cfg_aliases", @@ -272,22 +281,22 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytecheck" @@ -313,9 +322,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cast" @@ -325,9 +334,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.36" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "jobserver", @@ -337,9 +346,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -349,11 +358,10 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -387,7 +395,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] @@ -414,9 +422,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "duckdb" +name = "derive_arbitrary" version = "1.4.2" -source = "git+https://github.com/windmill-labs/duckdb-rs.git?rev=fe0702529de6ec5a568337726bba9355503157d2#fe0702529de6ec5a568337726bba9355503157d2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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.117", +] + +[[package]] +name = "duckdb" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8685352ce688883098b61a361e86e87df66fc8c444f4a2411e884c16d5243a65" dependencies = [ "arrow", "cast", @@ -437,12 +468,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -459,30 +490,30 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys", ] [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -491,6 +522,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[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 = "funty" version = "2.0.0" @@ -498,37 +538,91 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "getrandom" -version = "0.2.16" +name = "futures-channel" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", + "libc", + "wasi", + "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", - "wasi 0.14.4+wasi-0.2.4", + "wasip2", + "wasm-bindgen", ] [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", "num-traits", + "zerocopy", ] [[package]] @@ -551,9 +645,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashlink" @@ -571,10 +665,110 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "iana-time-zone" -version = "0.1.63" +name = "http" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "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 = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "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.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -595,20 +789,138 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "2.11.0" +name = "icu_collections" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[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 = "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 = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.1", +] + +[[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.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", ] [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" @@ -616,15 +928,15 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.78" +version = "0.3.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" dependencies = [ "once_cell", "wasm-bindgen", @@ -632,9 +944,9 @@ dependencies = [ [[package]] name = "lexical-core" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b765c31809609075565a70b4b71402281283aeda7ecaf4818ac14a7b2ade8958" +checksum = "7d8d125a277f807e55a77304455eb7b1cb52f2b18c143b60e766c120bd64a594" dependencies = [ "lexical-parse-float", "lexical-parse-integer", @@ -645,86 +957,82 @@ dependencies = [ [[package]] name = "lexical-parse-float" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de6f9cb01fb0b08060209a057c048fcbab8717b4c1ecd2eac66ebfe39a65b0f2" +checksum = "52a9f232fbd6f550bc0137dcb5f99ab674071ac2d690ac69704593cb4abbea56" dependencies = [ "lexical-parse-integer", "lexical-util", - "static_assertions", ] [[package]] name = "lexical-parse-integer" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72207aae22fc0a121ba7b6d479e42cbfea549af1479c3f3a4f12c70dd66df12e" +checksum = "9a7a039f8fb9c19c996cd7b2fcce303c1b2874fe1aca544edc85c4a5f8489b34" dependencies = [ "lexical-util", - "static_assertions", ] [[package]] name = "lexical-util" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a82e24bf537fd24c177ffbbdc6ebcc8d54732c35b50a3f28cc3f4e4c949a0b3" -dependencies = [ - "static_assertions", -] +checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" [[package]] name = "lexical-write-float" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5afc668a27f460fb45a81a757b6bf2f43c2d7e30cb5a2dcd3abf294c78d62bd" +checksum = "50c438c87c013188d415fbabbb1dceb44249ab81664efbd31b14ae55dabb6361" dependencies = [ "lexical-util", "lexical-write-integer", - "static_assertions", ] [[package]] name = "lexical-write-integer" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629ddff1a914a836fb245616a7888b62903aae58fa771e1d83943035efa0f978" +checksum = "409851a618475d2d5796377cad353802345cba92c867d9fbcde9cf4eac4e14df" dependencies = [ "lexical-util", - "static_assertions", ] [[package]] name = "libc" -version = "0.2.175" +version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "libduckdb-sys" -version = "1.4.2" -source = "git+https://github.com/windmill-labs/duckdb-rs.git?rev=fe0702529de6ec5a568337726bba9355503157d2#fe0702529de6ec5a568337726bba9355503157d2" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78bacb8933586cee3b550c39b610d314f9b7a48701ac7a914a046165a4ad8da" dependencies = [ "cc", "flate2", "pkg-config", + "reqwest", "serde", "serde_json", "tar", "vcpkg", + "zip", ] [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags", "libc", @@ -733,21 +1041,33 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "memchr" -version = "2.7.5" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miniz_oxide" @@ -756,6 +1076,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -838,12 +1170,39 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[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 = "pkg-config" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -855,18 +1214,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -892,10 +1251,65 @@ dependencies = [ ] [[package]] -name = "quote" -version = "1.0.40" +name = "quinn" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "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", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -919,8 +1333,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "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.5", ] [[package]] @@ -930,7 +1354,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "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.5", ] [[package]] @@ -939,23 +1373,32 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", ] [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -965,9 +1408,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -976,9 +1419,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rend" @@ -990,10 +1433,64 @@ dependencies = [ ] [[package]] -name = "rkyv" -version = "0.7.45" +name = "reqwest" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[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.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.7.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" dependencies = [ "bitvec", "bytecheck", @@ -1009,9 +1506,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.45" +version = "0.7.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" dependencies = [ "proc-macro2", "quote", @@ -1020,31 +1517,72 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.37.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" +checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" dependencies = [ "arrayvec", "borsh", "bytes", "num-traits", - "rand", + "rand 0.8.5", "rkyv", "serde", "serde_json", ] [[package]] -name = "rustix" -version = "1.0.8" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -1055,9 +1593,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "seahash" @@ -1067,33 +1605,56 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[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.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap", "itoa", "memchr", + "serde", + "serde_core", + "zmij", +] + +[[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", ] @@ -1104,6 +1665,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "simdutf8" version = "0.1.5" @@ -1111,10 +1678,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "slab" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strum" @@ -1141,7 +1730,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -1153,9 +1742,15 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -1169,15 +1764,35 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" 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.117", +] + [[package]] name = "tap" version = "1.0.1" @@ -1195,6 +1810,26 @@ dependencies = [ "xattr", ] +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1204,6 +1839,16 @@ dependencies = [ "crunchy", ] +[[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" @@ -1220,39 +1865,170 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "toml_datetime" -version = "0.6.11" +name = "tokio" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[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 = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", + "toml_parser", "winnow", ] [[package]] -name = "unicode-ident" -version = "1.0.18" +name = "toml_parser" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags", + "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.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.18.1" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" dependencies = [ "js-sys", "wasm-bindgen", @@ -1270,6 +2046,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[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.11.1+wasi-snapshot-preview1" @@ -1277,19 +2062,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.4+wasi-0.2.4" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.101" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" dependencies = [ "cfg-if", "once_cell", @@ -1299,24 +2084,24 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.101" +name = "wasm-bindgen-futures" +version = "0.4.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" +checksum = "8a89f4650b770e4521aa6573724e2aed4704372151bd0de9d16a3bbabb87441a" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1324,26 +2109,55 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.106", - "wasm-bindgen-backend", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "705eceb4ce901230f8625bd1d665128056ccbe4b7408faa625eec1ba80f59a97" +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 = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "windmill_duckdb_ffi_internal" version = "0.1.0" @@ -1357,9 +2171,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -1370,138 +2184,226 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] +[[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.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets", + "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", ] [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +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", - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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_aarch64_gnullvm" -version = "0.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +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.53.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +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.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.45.1" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wyz" @@ -1514,30 +2416,151 @@ dependencies = [ [[package]] name = "xattr" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", "rustix", ] [[package]] -name = "zerocopy" -version = "0.8.27" +name = "yoke" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +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.117", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", +] + +[[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.117", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[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.117", +] + +[[package]] +name = "zip" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b" +dependencies = [ + "arbitrary", + "crc32fast", + "flate2", + "indexmap", + "memchr", + "zopfli", +] + +[[package]] +name = "zlib-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c745c48e1007337ed136dc99df34128b9faa6ed542d80a1c673cf55a6d7236c8" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", ] diff --git a/backend/windmill-duckdb-ffi-internal/Cargo.toml b/backend/windmill-duckdb-ffi-internal/Cargo.toml index b1535daba9..7043b33ee5 100644 --- a/backend/windmill-duckdb-ffi-internal/Cargo.toml +++ b/backend/windmill-duckdb-ffi-internal/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] chrono = "0.4.41" -duckdb = { rev = "fe0702529de6ec5a568337726bba9355503157d2", git = "https://github.com/windmill-labs/duckdb-rs.git", features = ["bundled"] } +duckdb = { version = "1.4.4", features = ["bundled"] } rust_decimal = "1.37.2" serde = { version = "1.0", features = ["derive"] } serde_json = { version = "^1", features = ["preserve_order", "raw_value"] } diff --git a/backend/windmill-duckdb-ffi-internal/src/lib.rs b/backend/windmill-duckdb-ffi-internal/src/lib.rs index ee5396d45a..c5c819e60b 100644 --- a/backend/windmill-duckdb-ffi-internal/src/lib.rs +++ b/backend/windmill-duckdb-ffi-internal/src/lib.rs @@ -4,7 +4,7 @@ use std::{ ptr::null_mut, }; -use duckdb::{Row, params_from_iter, types::TimeUnit}; +use duckdb::{Row, core::LogicalTypeId, params_from_iter, types::TimeUnit}; use rust_decimal::{Decimal, prelude::FromPrimitive}; use serde::Deserialize; use serde_json::value::RawValue; @@ -267,7 +267,10 @@ fn do_duckdb_inner( (0..stmt.column_count()) .map(|i| { let logical_type = stmt.column_logical_type(i); - if logical_type.is_invalid() { + let logical_type_id = logical_type.id(); + let invalid = logical_type_id == LogicalTypeId::Invalid + || logical_type_id == LogicalTypeId::Unsupported; + if invalid { None } else { logical_type.get_alias() diff --git a/backend/windmill-jseval/src/lib.rs b/backend/windmill-jseval/src/lib.rs index bb0f27ee2b..89feaf7b3e 100644 --- a/backend/windmill-jseval/src/lib.rs +++ b/backend/windmill-jseval/src/lib.rs @@ -274,16 +274,19 @@ pub async fn eval_timeout_quickjs( let expr_clone = expr.clone(); - // Run the QuickJS evaluation with a timeout + // Run the QuickJS evaluation with a timeout. + // Use the current runtime handle rather than creating an independent + // current-thread runtime so that HTTP connections opened by the global + // reqwest client (HTTP_CLIENT) are managed by the main runtime. + // Creating a child runtime caused connection-pool dispatch tasks to be + // dropped when the child runtime exited, poisoning pooled connections + // and producing spurious "DispatchGone" / "runtime dropped the dispatch + // task" errors on subsequent requests from the main runtime. + let handle = tokio::runtime::Handle::current(); tokio::time::timeout( std::time::Duration::from_millis(EVAL_TIMEOUT_MS), tokio::task::spawn_blocking(move || { - // Create a new tokio runtime for async operations within the blocking context - let rt = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build()?; - - rt.block_on(async move { + handle.block_on(async move { eval_quickjs_inner( &expr_clone, filtered_context, @@ -300,7 +303,9 @@ pub async fn eval_timeout_quickjs( ) .await .map_err(|_| { - anyhow::anyhow!("The expression evaluation `{expr}` took too long to execute (>{EVAL_TIMEOUT_MS}ms)") + anyhow::anyhow!( + "The expression evaluation `{expr}` took too long to execute (>{EVAL_TIMEOUT_MS}ms)" + ) })?? } @@ -787,13 +792,11 @@ pub async fn eval_simple_js( expr: String, globals: HashMap, ) -> anyhow::Result> { + let handle = tokio::runtime::Handle::current(); tokio::time::timeout( std::time::Duration::from_millis(EVAL_TIMEOUT_MS), tokio::task::spawn_blocking(move || { - let rt = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build()?; - rt.block_on(async move { + handle.block_on(async move { let runtime = AsyncRuntime::new()?; runtime.set_memory_limit(QUICKJS_MEMORY_LIMIT).await; let context = AsyncContext::full(&runtime).await?; diff --git a/backend/windmill-trigger-postgres/src/converter.rs b/backend/windmill-trigger-postgres/src/converter.rs index 172b62df77..7fe7de92b9 100644 --- a/backend/windmill-trigger-postgres/src/converter.rs +++ b/backend/windmill-trigger-postgres/src/converter.rs @@ -361,19 +361,13 @@ mod tests { fn test_timestamp() { let result = Converter::try_from_str(Some(Type::TIMESTAMP), "2024-01-15 14:30:00.0").unwrap(); - assert_eq!( - result, - Value::String("2024-01-15 14:30:00".to_string()) - ); + assert_eq!(result, Value::String("2024-01-15 14:30:00".to_string())); } #[test] fn test_timestamptz() { - let result = Converter::try_from_str( - Some(Type::TIMESTAMPTZ), - "2024-01-15 14:30:00.0+00", - ) - .unwrap(); + let result = + Converter::try_from_str(Some(Type::TIMESTAMPTZ), "2024-01-15 14:30:00.0+00").unwrap(); assert!(result.as_str().unwrap().contains("2024-01-15")); } @@ -484,8 +478,7 @@ mod tests { #[test] fn test_array_with_escaped_backslash() { - let result = - Converter::try_from_str(Some(Type::TEXT_ARRAY), r#"{"a\\b","c"}"#).unwrap(); + let result = Converter::try_from_str(Some(Type::TEXT_ARRAY), r#"{"a\\b","c"}"#).unwrap(); assert_eq!(result, json!(["a\\b", "c"])); } diff --git a/backend/windmill-trigger-postgres/src/lib.rs b/backend/windmill-trigger-postgres/src/lib.rs index 011453739c..d6fcebfddb 100644 --- a/backend/windmill-trigger-postgres/src/lib.rs +++ b/backend/windmill-trigger-postgres/src/lib.rs @@ -1,8 +1,5 @@ use std::collections::HashMap; -use windmill_api_auth::ApiAuthed; -use windmill_store::resources::try_get_resource_from_db_as; -use windmill_trigger::trigger_helpers::TriggerJobArgs; use chrono::Utc; use itertools::Itertools; use native_tls::{Certificate, TlsConnector}; @@ -13,6 +10,8 @@ use rust_postgres_native_tls::MakeTlsConnector; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::value::RawValue; use sqlx::FromRow; +use windmill_api_auth::ApiAuthed; +use windmill_common::workspaces::get_datatable_resource_from_db_unchecked; use windmill_common::{ db::UserDB, error::{to_anyhow, Error, Result}, @@ -20,6 +19,8 @@ use windmill_common::{ utils::empty_as_none, DB, }; +use windmill_store::resources::try_get_resource_from_db_as; +use windmill_trigger::trigger_helpers::TriggerJobArgs; mod bool; mod converter; @@ -373,6 +374,26 @@ pub async fn get_raw_postgres_connection( Ok(client) } +pub async fn resolve_postgres_resource( + authed: &ApiAuthed, + user_db: Option, + db: &DB, + postgres_resource_path: &str, + w_id: &str, +) -> Result { + if let Some(datatable_name) = postgres_resource_path.strip_prefix("datatable://") { + let resource_value = + get_datatable_resource_from_db_unchecked(db, w_id, datatable_name).await?; + serde_json::from_value::(resource_value).map_err(|e| Error::SerdeJson { + error: e, + location: "resolve_postgres_resource".to_string(), + }) + } else { + try_get_resource_from_db_as::(authed, user_db, db, postgres_resource_path, w_id) + .await + } +} + pub async fn get_pg_connection( authed: ApiAuthed, user_db: Option, @@ -382,8 +403,7 @@ pub async fn get_pg_connection( logical_mode: bool, ) -> Result { let database = - try_get_resource_from_db_as::(&authed, user_db, db, postgres_resource_path, w_id) - .await?; + resolve_postgres_resource(&authed, user_db, db, postgres_resource_path, w_id).await?; Ok(get_raw_postgres_connection(&database, logical_mode).await?) } diff --git a/backend/windmill-trigger-postgres/src/listener.rs b/backend/windmill-trigger-postgres/src/listener.rs index cc71cedd33..eda9cdb8aa 100644 --- a/backend/windmill-trigger-postgres/src/listener.rs +++ b/backend/windmill-trigger-postgres/src/listener.rs @@ -15,7 +15,6 @@ use windmill_common::{ DB, }; -use windmill_store::resources::try_get_resource_from_db_as; use windmill_trigger::{listener::ListeningTrigger, trigger_helpers::TriggerJobArgs, Listener}; use super::{ @@ -26,7 +25,8 @@ use super::{ LogicalReplicationMessage::{Begin, Commit, Delete, Insert, Relation, Type, Update}, PrimaryKeepAliveBody, ReplicationMessage, }, - Postgres, PostgresConfig, PostgresTrigger, ERROR_PUBLICATION_NAME_NOT_EXISTS, + resolve_postgres_resource, Postgres, PostgresConfig, PostgresTrigger, + ERROR_PUBLICATION_NAME_NOT_EXISTS, }; const ERROR_REPLICATION_SLOT_NOT_EXISTS: &str = r#"The replication slot associated with this trigger no longer exists. Recreate a new replication slot or select an existing one in the advanced tab, or delete and recreate a new trigger"#; @@ -147,7 +147,7 @@ impl Listener for PostgresTrigger { .authed(db, &Self::TRIGGER_KIND.to_string()) .await?; - let database = try_get_resource_from_db_as::( + let database = resolve_postgres_resource( &authed, Some(UserDB::new(db.clone())), &db, diff --git a/backend/windmill-trigger-postgres/src/mapper.rs b/backend/windmill-trigger-postgres/src/mapper.rs index abd40a2838..13b75fbb0e 100644 --- a/backend/windmill-trigger-postgres/src/mapper.rs +++ b/backend/windmill-trigger-postgres/src/mapper.rs @@ -180,7 +180,10 @@ mod tests { fn test_postgres_to_typescript_date_types() { assert_eq!(postgres_to_typescript_type(Some(Type::DATE)), "string"); assert_eq!(postgres_to_typescript_type(Some(Type::TIMESTAMP)), "string"); - assert_eq!(postgres_to_typescript_type(Some(Type::TIMESTAMPTZ)), "string"); + assert_eq!( + postgres_to_typescript_type(Some(Type::TIMESTAMPTZ)), + "string" + ); assert_eq!(postgres_to_typescript_type(Some(Type::UUID)), "string"); } diff --git a/backend/windmill-trigger-postgres/src/relation.rs b/backend/windmill-trigger-postgres/src/relation.rs index 0907c134cf..c9ca338766 100644 --- a/backend/windmill-trigger-postgres/src/relation.rs +++ b/backend/windmill-trigger-postgres/src/relation.rs @@ -80,10 +80,17 @@ mod tests { use rust_postgres::types::Type; use serde_json::json; - use super::super::replication_message::{Column, ReplicaIdentity, RelationBody}; + use super::super::replication_message::{Column, RelationBody, ReplicaIdentity}; fn make_relation(o_id: Oid, columns: Vec) -> RelationBody { - RelationBody::new(None, o_id, "public".to_string(), "test".to_string(), ReplicaIdentity::Default, columns) + RelationBody::new( + None, + o_id, + "public".to_string(), + "test".to_string(), + ReplicaIdentity::Default, + columns, + ) } fn text_col(name: &str, typ: Option) -> Column { @@ -93,10 +100,13 @@ mod tests { #[test] fn test_row_to_json_text_columns() { let mut converter = RelationConverter::new(); - converter.add_relation(make_relation(1, vec![ - text_col("id", Some(Type::INT4)), - text_col("name", Some(Type::TEXT)), - ])); + converter.add_relation(make_relation( + 1, + vec![ + text_col("id", Some(Type::INT4)), + text_col("name", Some(Type::TEXT)), + ], + )); let tuple = vec![ TupleData::Text(Bytes::from("42")), @@ -111,15 +121,15 @@ mod tests { #[test] fn test_row_to_json_with_null() { let mut converter = RelationConverter::new(); - converter.add_relation(make_relation(1, vec![ - text_col("id", Some(Type::INT4)), - text_col("email", Some(Type::TEXT)), - ])); + converter.add_relation(make_relation( + 1, + vec![ + text_col("id", Some(Type::INT4)), + text_col("email", Some(Type::TEXT)), + ], + )); - let tuple = vec![ - TupleData::Text(Bytes::from("1")), - TupleData::Null, - ]; + let tuple = vec![TupleData::Text(Bytes::from("1")), TupleData::Null]; let result = converter.row_to_json((1, tuple)).unwrap(); assert_eq!(result["id"], json!(1)); @@ -129,9 +139,7 @@ mod tests { #[test] fn test_row_to_json_with_unchanged_toast() { let mut converter = RelationConverter::new(); - converter.add_relation(make_relation(1, vec![ - text_col("data", Some(Type::TEXT)), - ])); + converter.add_relation(make_relation(1, vec![text_col("data", Some(Type::TEXT))])); let tuple = vec![TupleData::UnchangedToast]; let result = converter.row_to_json((1, tuple)).unwrap(); @@ -141,9 +149,7 @@ mod tests { #[test] fn test_row_to_json_binary_rejected() { let mut converter = RelationConverter::new(); - converter.add_relation(make_relation(1, vec![ - text_col("data", Some(Type::BYTEA)), - ])); + converter.add_relation(make_relation(1, vec![text_col("data", Some(Type::BYTEA))])); let tuple = vec![TupleData::Binary(Bytes::from("data"))]; assert!(matches!( @@ -168,8 +174,12 @@ mod tests { converter.add_relation(make_relation(1, vec![text_col("a", Some(Type::TEXT))])); converter.add_relation(make_relation(2, vec![text_col("b", Some(Type::INT4))])); - let result1 = converter.row_to_json((1, vec![TupleData::Text(Bytes::from("hello"))])).unwrap(); - let result2 = converter.row_to_json((2, vec![TupleData::Text(Bytes::from("42"))])).unwrap(); + let result1 = converter + .row_to_json((1, vec![TupleData::Text(Bytes::from("hello"))])) + .unwrap(); + let result2 = converter + .row_to_json((2, vec![TupleData::Text(Bytes::from("42"))])) + .unwrap(); assert_eq!(result1["a"], json!("hello")); assert_eq!(result2["b"], json!(42)); @@ -178,11 +188,11 @@ mod tests { #[test] fn test_row_to_json_bool_column() { let mut converter = RelationConverter::new(); - converter.add_relation(make_relation(1, vec![ - text_col("active", Some(Type::BOOL)), - ])); + converter.add_relation(make_relation(1, vec![text_col("active", Some(Type::BOOL))])); - let result = converter.row_to_json((1, vec![TupleData::Text(Bytes::from("t"))])).unwrap(); + let result = converter + .row_to_json((1, vec![TupleData::Text(Bytes::from("t"))])) + .unwrap(); assert_eq!(result["active"], json!(true)); } } diff --git a/backend/windmill-trigger-postgres/src/replication_message.rs b/backend/windmill-trigger-postgres/src/replication_message.rs index 43dba75889..1c82dd978e 100644 --- a/backend/windmill-trigger-postgres/src/replication_message.rs +++ b/backend/windmill-trigger-postgres/src/replication_message.rs @@ -682,10 +682,7 @@ mod tests { #[test] fn test_parse_insert_with_null_tuple() { - let data = Bytes::from(build_insert_message( - 10, - &[(TUPLE_DATA_NULL_BYTE, &[])], - )); + let data = Bytes::from(build_insert_message(10, &[(TUPLE_DATA_NULL_BYTE, &[])])); let body = XLogDataBody::new(0, 0, 0, data); match body.parse(&settings(false)).unwrap() { LogicalReplicationMessage::Insert(insert) => { @@ -698,10 +695,7 @@ mod tests { #[test] fn test_parse_insert_with_toast_tuple() { - let data = Bytes::from(build_insert_message( - 10, - &[(TUPLE_DATA_TOAST_BYTE, &[])], - )); + let data = Bytes::from(build_insert_message(10, &[(TUPLE_DATA_TOAST_BYTE, &[])])); let body = XLogDataBody::new(0, 0, 0, data); match body.parse(&settings(false)).unwrap() { LogicalReplicationMessage::Insert(insert) => { @@ -759,7 +753,7 @@ mod tests { buf.extend_from_slice(b"users\0"); // name buf.push(REPLICA_IDENTITY_DEFAULT_BYTE as u8); // replica identity buf.extend_from_slice(&1i16.to_be_bytes()); // num columns - // column: flags=0, name="id", type_oid=23 (INT4), type_modifier=-1 + // column: flags=0, name="id", type_oid=23 (INT4), type_modifier=-1 buf.push(0); // flags buf.extend_from_slice(b"id\0"); // name buf.extend_from_slice(&23u32.to_be_bytes()); // type_oid (INT4) diff --git a/backend/windmill-worker/src/worker_flow.rs b/backend/windmill-worker/src/worker_flow.rs index bc630b3190..4d71bb1695 100644 --- a/backend/windmill-worker/src/worker_flow.rs +++ b/backend/windmill-worker/src/worker_flow.rs @@ -1099,21 +1099,22 @@ pub async fn update_flow_status_after_job_completion_internal( || (flow_jobs.is_some() && (skip_loop_failures || skip_seq_branch_failure))) && !(stop_early && stop_early_err_msg.is_some() && !skip_if_stop_early) { - let is_skipped = if current_module.as_ref().is_some_and(|m| m.skip_if.is_some()) - { - sqlx::query_scalar!( - "SELECT kind = 'identity' FROM v2_job WHERE id = $1", - job_id_for_status - ) - .fetch_one(db) - .await - .map_err(|e| { - Error::internal_err(format!("error during skip check: {e:#}")) - })? - .unwrap_or(false) - } else { - stop_early && skip_if_stop_early // Mark as skipped when stop_after_if with skip_if_stopped=true - }; + let is_skipped = (stop_early && skip_if_stop_early) + || if current_module.as_ref().is_some_and(|m| m.skip_if.is_some()) { + sqlx::query_scalar!( + "SELECT kind = 'identity' FROM v2_job WHERE id = $1", + job_id_for_status + ) + .fetch_optional(db) + .await + .map_err(|e| { + Error::internal_err(format!("error during skip check: {e:#}")) + })? + .flatten() + .unwrap_or(false) + } else { + false + }; success = true; ( true, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 886cbdaa22..769d68610c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -102,9 +102,9 @@ "@melt-ui/svelte": "^0.86.2", "@playwright/test": "^1.57.0", "@sveltejs/adapter-static": "^3.0.6", - "@sveltejs/kit": "^2.49.2", - "@sveltejs/package": "^2.3.7", - "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@sveltejs/kit": "^2.53.2", + "@sveltejs/package": "^2.5.7", + "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.8", "@types/d3": "^7.4.0", @@ -131,9 +131,9 @@ "prettier-plugin-svelte": "^3.3.3", "style-to-object": "^0.4.1", "stylelint-config-recommended": "^13.0.0", - "svelte": "^5.38.0", + "svelte": "^5.53.5", "svelte-awesome-color-picker": "^3.0.4", - "svelte-check": "^4.0.0", + "svelte-check": "^4.4.3", "svelte-fast-check": "^0.4.5", "svelte-floating-ui": "^1.5.8", "svelte-highlight": "^7.6.0", @@ -835,7 +835,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -847,7 +846,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -858,7 +856,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1348,7 +1345,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz", "integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1503,7 +1499,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1520,7 +1515,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1537,7 +1531,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1554,7 +1547,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1571,7 +1563,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1588,7 +1579,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1605,7 +1595,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1622,7 +1611,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1639,7 +1627,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1656,7 +1643,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1673,7 +1659,6 @@ "cpu": [ "wasm32" ], - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1690,7 +1675,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1707,7 +1691,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2102,9 +2085,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.49.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.49.2.tgz", - "integrity": "sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==", + "version": "2.53.2", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.53.2.tgz", + "integrity": "sha512-M+MqAvFve12T1HWws/2npP/s3hFtyjw3GB/OXW/8a1jZBk48qnvPJrtgE+VOMc3RnjUMxc4mv/vQ73nvj2uNMg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2113,13 +2096,12 @@ "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", - "devalue": "^5.3.2", + "devalue": "^5.6.3", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", + "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "bin": { @@ -2130,24 +2112,28 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "peerDependenciesMeta": { "@opentelemetry/api": { "optional": true + }, + "typescript": { + "optional": true } } }, "node_modules/@sveltejs/package": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.5.4.tgz", - "integrity": "sha512-8+1hccAt0M3PPkHVPKH54Wc+cc1PNxRqCrICZiv/hEEto8KwbQVRghxNgTB4htIPyle+4CIB8RayTQH5zRQh9A==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.5.7.tgz", + "integrity": "sha512-qqD9xa9H7TDiGFrF6rz7AirOR8k15qDK/9i4MIE8te4vWsv5GEogPks61rrZcLy+yWph+aI6pIj2MdoK3YI8AQ==", "dev": true, "license": "MIT", "dependencies": { - "chokidar": "^4.0.3", + "chokidar": "^5.0.0", "kleur": "^4.1.5", "sade": "^1.8.1", "semver": "^7.5.4", @@ -2163,17 +2149,47 @@ "svelte": "^3.44.0 || ^4.0.0 || ^5.0.0-next.1" } }, + "node_modules/@sveltejs/package/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sveltejs/package/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz", - "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz", + "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", "devOptional": true, "license": "MIT", "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", - "debug": "^4.4.1", "deepmerge": "^4.3.1", - "magic-string": "^0.30.17", + "magic-string": "^0.30.21", + "obug": "^2.1.0", "vitefu": "^1.1.1" }, "engines": { @@ -2313,7 +2329,6 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2723,8 +2738,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/@types/unist": { "version": "3.0.3", @@ -3442,9 +3456,9 @@ "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -4971,10 +4985,9 @@ } }, "node_modules/devalue": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.3.2.tgz", - "integrity": "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==", - "devOptional": true, + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", "license": "MIT" }, "node_modules/devlop": { @@ -5705,9 +5718,9 @@ } }, "node_modules/esrap": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", - "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.3.tgz", + "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -7193,7 +7206,7 @@ "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -7692,7 +7705,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7713,7 +7725,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7734,7 +7745,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7755,7 +7765,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7776,7 +7785,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7797,7 +7805,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7818,7 +7825,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7839,7 +7845,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7860,7 +7865,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7881,7 +7885,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7902,7 +7905,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9234,7 +9236,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -9541,7 +9543,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", - "dev": true, + "devOptional": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" @@ -11566,7 +11568,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "mri": "^1.1.0" @@ -11615,9 +11617,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz", + "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==", "devOptional": true, "license": "MIT" }, @@ -12430,21 +12432,23 @@ } }, "node_modules/svelte": { - "version": "5.39.12", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.12.tgz", - "integrity": "sha512-CEzwxFuEycokU8K8CE/OuwVbmei+ivu2HvBGYIdASfMa1hCRSNr4RRkzNSvbAvu6h+BOig2CsZTAEY+WKvwZpA==", + "version": "5.53.5", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.53.5.tgz", + "integrity": "sha512-YkqERnF05g8KLdDZwZrF8/i1eSbj6Eoat8Jjr2IfruZz9StLuBqo8sfCSzjosNKd+ZrQ8DkKZDjpO5y3ht1Pow==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", - "aria-query": "^5.3.1", + "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", + "devalue": "^5.6.3", "esm-env": "^1.2.1", - "esrap": "^2.1.0", + "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -12488,9 +12492,9 @@ } }, "node_modules/svelte-check": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.3.tgz", - "integrity": "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.3.tgz", + "integrity": "sha512-4HtdEv2hOoLCEsSXI+RDELk9okP/4sImWa7X02OjMFFOWeSdFF3NFy3vqpw0z+eH9C88J9vxZfUXz/Uv2A1ANw==", "dev": true, "license": "MIT", "dependencies": { @@ -12529,21 +12533,6 @@ } } }, - "node_modules/svelte-check/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/svelte-eslint-parser": { "version": "0.43.0", "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz", @@ -13274,7 +13263,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/frontend/package.json b/frontend/package.json index 61c6a994bd..b0922a809d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,9 +27,9 @@ "@melt-ui/svelte": "^0.86.2", "@playwright/test": "^1.57.0", "@sveltejs/adapter-static": "^3.0.6", - "@sveltejs/kit": "^2.49.2", - "@sveltejs/package": "^2.3.7", - "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@sveltejs/kit": "^2.53.2", + "@sveltejs/package": "^2.5.7", + "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.8", "@types/d3": "^7.4.0", @@ -56,9 +56,9 @@ "prettier-plugin-svelte": "^3.3.3", "style-to-object": "^0.4.1", "stylelint-config-recommended": "^13.0.0", - "svelte": "^5.38.0", + "svelte": "^5.53.5", "svelte-awesome-color-picker": "^3.0.4", - "svelte-check": "^4.0.0", + "svelte-check": "^4.4.3", "svelte-fast-check": "^0.4.5", "svelte-floating-ui": "^1.5.8", "svelte-highlight": "^7.6.0", diff --git a/frontend/src/lib/aiStore.ts b/frontend/src/lib/aiStore.ts index 6b302d281f..8abc303e18 100644 --- a/frontend/src/lib/aiStore.ts +++ b/frontend/src/lib/aiStore.ts @@ -9,113 +9,116 @@ const USER_CUSTOM_PROMPTS_KEY = 'userCustomAIPrompts' const sessionModel = getLocalSetting(COPILOT_SESSION_MODEL_SETTING_NAME) const sessionProvider = getLocalSetting(COPILOT_SESSION_PROVIDER_SETTING_NAME) export const copilotSessionModel = writable( - sessionModel && sessionProvider - ? { - model: sessionModel, - provider: sessionProvider as AIProvider - } - : undefined + sessionModel && sessionProvider + ? { + model: sessionModel, + provider: sessionProvider as AIProvider + } + : undefined ) - export const copilotInfo = writable<{ - enabled: boolean - codeCompletionModel?: AIProviderModel - defaultModel?: AIProviderModel - aiModels: AIProviderModel[] - customPrompts?: Record - maxTokensPerModel?: Record + enabled: boolean + codeCompletionModel?: AIProviderModel + defaultModel?: AIProviderModel + aiModels: AIProviderModel[] + customPrompts?: Record + maxTokensPerModel?: Record }>({ - enabled: false, - codeCompletionModel: undefined, - defaultModel: undefined, - aiModels: [], - customPrompts: {}, - maxTokensPerModel: {} + enabled: false, + codeCompletionModel: undefined, + defaultModel: undefined, + aiModels: [], + customPrompts: {}, + maxTokensPerModel: {} }) export async function loadCopilot(workspace: string) { - workspaceAIClients.init(workspace) - try { - const info = await WorkspaceService.getCopilotInfo({ workspace }) - setCopilotInfo(info) - } catch (err) { - setCopilotInfo({}) - console.error('Could not get copilot info', err) - } + workspaceAIClients.init(workspace) + try { + const info = await WorkspaceService.getCopilotInfo({ workspace }) + setCopilotInfo(info) + } catch (err) { + setCopilotInfo({}) + console.error('Could not get copilot info', err) + } } export function setCopilotInfo(aiConfig: AIConfig) { - if (Object.keys(aiConfig.providers ?? {}).length > 0) { - const aiModels = Object.entries(aiConfig.providers ?? {}).flatMap( - ([provider, providerConfig]) => - providerConfig.models.map((m) => ({ model: m, provider: provider as AIProvider })) - ) + if (Object.keys(aiConfig.providers ?? {}).length > 0) { + const aiModels = Object.entries(aiConfig.providers ?? {}).flatMap( + ([provider, providerConfig]) => + providerConfig.models.map((m) => ({ model: m, provider: provider as AIProvider })) + ) - copilotSessionModel.update((model) => { - if ( - model && - !aiModels.some((m) => m.model === model.model && m.provider === model.provider) - ) { - return undefined - } - return model - }) + copilotSessionModel.update((model) => { + if ( + model && + !aiModels.some((m) => m.model === model.model && m.provider === model.provider) + ) { + return undefined + } + return model + }) - copilotInfo.set({ - enabled: true, - codeCompletionModel: aiConfig.code_completion_model, - defaultModel: aiConfig.default_model, - aiModels: aiModels, - customPrompts: aiConfig.custom_prompts ?? {}, - maxTokensPerModel: aiConfig.max_tokens_per_model ?? {} - }) - } else { - copilotSessionModel.set(undefined) + copilotInfo.set({ + enabled: true, + codeCompletionModel: aiConfig.code_completion_model, + defaultModel: aiConfig.default_model, + aiModels: aiModels, + customPrompts: aiConfig.custom_prompts ?? {}, + maxTokensPerModel: aiConfig.max_tokens_per_model ?? {} + }) + } else { + copilotSessionModel.set(undefined) - copilotInfo.set({ - enabled: false, - codeCompletionModel: undefined, - defaultModel: undefined, - aiModels: [], - customPrompts: {}, - maxTokensPerModel: {} - }) - } + copilotInfo.set({ + enabled: false, + codeCompletionModel: undefined, + defaultModel: undefined, + aiModels: [], + customPrompts: {}, + maxTokensPerModel: {} + }) + } } -export function getCurrentModel() { - const model = - get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0] - if (!model) { - throw new Error('No model selected') - } - return model +export function getCurrentModel(): AIProviderModel { + const model = + get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0] + if (!model) { + throw new Error('No model selected') + } + return model +} + +export function tryGetCurrentModel(): AIProviderModel | undefined { + return get(copilotSessionModel) ?? get(copilotInfo).defaultModel ?? get(copilotInfo).aiModels[0] } export function getUserCustomPrompts(): Record { - const stored = getLocalSetting(USER_CUSTOM_PROMPTS_KEY) - if (stored) { - try { - return JSON.parse(stored) - } catch (e) { - console.error('Failed to parse user custom prompts', e) - return {} - } - } - return {} + const stored = getLocalSetting(USER_CUSTOM_PROMPTS_KEY) + if (stored) { + try { + return JSON.parse(stored) + } catch (e) { + console.error('Failed to parse user custom prompts', e) + return {} + } + } + return {} } export function getCombinedCustomPrompt(mode: string): string | undefined { - const workspacePrompt = get(copilotInfo).customPrompts?.[mode] - const userPrompts = getUserCustomPrompts() - const userPrompt = userPrompts[mode] + const workspacePrompt = get(copilotInfo).customPrompts?.[mode] + const userPrompts = getUserCustomPrompts() + const userPrompt = userPrompts[mode] - const prompts = [workspacePrompt, userPrompt].filter((p) => p?.trim()) + const prompts = [workspacePrompt, userPrompt].filter((p) => p?.trim()) - if (prompts.length === 0) { - return undefined - } + if (prompts.length === 0) { + return undefined + } - return prompts.join('\n\n') + return prompts.join('\n\n') } diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 328d43ca20..8e4c072971 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -1057,6 +1057,7 @@ {:else if inputCat == 'resource-object' && (resourceTypes == undefined || (format && format?.split('-').length > 1 && resourceTypes.includes(format?.substring('resource-'.length))))} { @@ -438,6 +456,235 @@ diff })) ) + + // --- Fork Triggers --- + + type ForkTrigger = { + path: string + triggerKind: TriggerKind + scriptPath: string + isFlow: boolean + enabled?: boolean + extraLabel?: string + } + + let forkTriggers = $state([]) + let loadingTriggers = $state(true) + let deploymentDrawer: DeployWorkspaceDrawer | undefined = $state(undefined) + let triggerToDelete = $state(undefined) + + /** Deployable trigger kinds and their list+delete services */ + const triggerServices = { + schedules: { + list: (ws: string) => ScheduleService.listSchedules({ workspace: ws }), + delete: (ws: string, path: string) => ScheduleService.deleteSchedule({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'schedules', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.enabled, + extraLabel: item.schedule + }) + }, + routes: { + list: (ws: string) => HttpTriggerService.listHttpTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + HttpTriggerService.deleteHttpTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'routes', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: `${(item.http_method ?? 'get').toUpperCase()} ${item.route_path ?? ''}` + }) + }, + websockets: { + list: (ws: string) => WebsocketTriggerService.listWebsocketTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + WebsocketTriggerService.deleteWebsocketTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'websockets', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: item.url + }) + }, + kafka: { + list: (ws: string) => KafkaTriggerService.listKafkaTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + KafkaTriggerService.deleteKafkaTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'kafka', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: item.topics?.join(', ') + }) + }, + postgres: { + list: (ws: string) => PostgresTriggerService.listPostgresTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + PostgresTriggerService.deletePostgresTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'postgres', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled' + }) + }, + nats: { + list: (ws: string) => NatsTriggerService.listNatsTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + NatsTriggerService.deleteNatsTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'nats', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: item.subjects?.join(', ') + }) + }, + mqtt: { + list: (ws: string) => MqttTriggerService.listMqttTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + MqttTriggerService.deleteMqttTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'mqtt', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled' + }) + }, + sqs: { + list: (ws: string) => SqsTriggerService.listSqsTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + SqsTriggerService.deleteSqsTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'sqs', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: item.queue_url + }) + }, + gcp: { + list: (ws: string) => GcpTriggerService.listGcpTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + GcpTriggerService.deleteGcpTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'gcp', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: item.topic_id + }) + }, + emails: { + list: (ws: string) => EmailTriggerService.listEmailTriggers({ workspace: ws }), + delete: (ws: string, path: string) => + EmailTriggerService.deleteEmailTrigger({ workspace: ws, path }), + normalize: (item: any): ForkTrigger => ({ + path: item.path, + triggerKind: 'emails', + scriptPath: item.script_path, + isFlow: item.is_flow, + enabled: item.mode === 'enabled', + extraLabel: getEmailAddress( + item.local_part, + item.workspaced_local_part, + currentWorkspaceId, + emailDomain ?? '' + ) + }) + } + } as const + + let emailDomain = $state(undefined) + + async function fetchAllTriggers() { + loadingTriggers = true + try { + emailDomain = await getEmailDomain() + const entries = Object.values(triggerServices) + const results = await Promise.allSettled( + entries.map(async (svc) => { + const items = await svc.list(currentWorkspaceId) + return items.map(svc.normalize) + }) + ) + forkTriggers = results.flatMap((r) => (r.status === 'fulfilled' ? r.value : [])) + } catch (e) { + console.error('Failed to fetch fork triggers:', e) + forkTriggers = [] + } finally { + loadingTriggers = false + } + } + + function deleteTrigger(trigger: ForkTrigger) { + triggerToDelete = trigger + } + + async function confirmDeleteTrigger() { + const trigger = triggerToDelete + if (!trigger) return + triggerToDelete = undefined + const triggerType = triggerKindToTriggerType(trigger.triggerKind) + const displayName = triggerType ? triggerDisplayNamesMap[triggerType] : trigger.triggerKind + try { + const svc = triggerServices[trigger.triggerKind as keyof typeof triggerServices] + if (!svc) { + throw new Error(`No service for trigger kind: ${trigger.triggerKind}`) + } + await svc.delete(currentWorkspaceId, trigger.path) + forkTriggers = forkTriggers.filter( + (t) => !(t.path === trigger.path && t.triggerKind === trigger.triggerKind) + ) + sendUserToast(`Deleted ${displayName} trigger '${trigger.path}'`) + } catch (e: any) { + sendUserToast(`Failed to delete trigger '${trigger.path}': ${e.body || e.message}`, true) + } + } + + function getTriggerDisplayName(triggerKind: TriggerKind): string { + const triggerType = triggerKindToTriggerType(triggerKind) + return triggerType ? triggerDisplayNamesMap[triggerType] : triggerKind + } + + const triggerKindToPagePath: Record = { + schedules: '/schedules', + routes: '/routes', + websockets: '/websocket_triggers', + kafka: '/kafka_triggers', + postgres: '/postgres_triggers', + nats: '/nats_triggers', + mqtt: '/mqtt_triggers', + sqs: '/sqs_triggers', + gcp: '/gcp_triggers', + emails: '/email_triggers' + } + + function getTriggerHref(triggerKind: TriggerKind): string | undefined { + const pagePath = triggerKindToPagePath[triggerKind] + return pagePath ? `${base}${pagePath}` : undefined + } + + // Fetch triggers when workspace is available + $effect(() => { + if (currentWorkspaceId) { + fetchAllTriggers() + } + }) {#if $workspaceStore != currentWorkspaceId} @@ -725,9 +972,8 @@ You must set the "on behalf of" user for all items before deploying - The "run on behalf of" field defines which user's permissions will be - applied during execution. Make sure this is set to an appropriate - user before deploying. + The "run on behalf of" field defines which user's permissions will be applied + during execution. Make sure this is set to an appropriate user before deploying. {/if} @@ -749,7 +995,99 @@ {/snippet} + + +
+
+

Triggers created in this fork

+ {#if !loadingTriggers} + {forkTriggers.length} trigger{forkTriggers.length !== 1 ? 's' : ''} + {/if} +
+ + + When forking a workspace, triggers are not forked to avoid unnecessary executions or + collisions. If you created this triggers with the intention of deploying them to the parent + workspace, you can do so here. Otherwise it is recommended to delete them or disable them. + + + {#if loadingTriggers} +
+ + Loading triggers... +
+ {:else if forkTriggers.length === 0} +
+ No triggers in this fork workspace. +
+ {:else} +
+ {#each forkTriggers as trigger (trigger.triggerKind + ':' + trigger.path)} + + {#snippet customSummary()} + {getTriggerDisplayName(trigger.triggerKind)} + → + {trigger.scriptPath} + {#if trigger.isFlow} + flow + {/if} + {#if trigger.extraLabel} + ({trigger.extraLabel}) + {/if} + {/snippet} + {#snippet actions()} + {#if trigger.enabled != null} + + {trigger.enabled ? 'Enabled' : 'Disabled'} + + {/if} + + + {/snippet} + + {/each} +
+ {/if} +
+ + + (triggerToDelete = undefined)} + > + {#if triggerToDelete} + Are you sure you want to delete the {getTriggerDisplayName(triggerToDelete.triggerKind)} trigger + '{triggerToDelete.path}'? + {/if} + {:else}
No comparison data available
diff --git a/frontend/src/lib/components/ObjectResourceInput.svelte b/frontend/src/lib/components/ObjectResourceInput.svelte index e9033ee07d..e9f6e4d6e3 100644 --- a/frontend/src/lib/components/ObjectResourceInput.svelte +++ b/frontend/src/lib/components/ObjectResourceInput.svelte @@ -18,6 +18,7 @@ editor?: SimpleEditor | undefined path?: string disabled?: boolean + datatableAsPgResource?: boolean onClear?: () => void } @@ -30,16 +31,23 @@ defaultValue, editor = $bindable(undefined), disabled = false, + datatableAsPgResource = false, onClear = undefined }: Props = $props() function isResource() { - return isString(value) && value.length >= '$res:'.length + return isString(value) && value.startsWith('$res:') + } + + function isDatatable(val: any): boolean { + return (isString(val) && val.startsWith('datatable://')) || val === 'datatable' } function valueToPath() { if (isResource()) { return value.substr('$res:'.length) + } else if (isDatatable(value)) { + return value } } @@ -50,6 +58,7 @@ {:else if value == undefined || typeof value === 'string'} - import { ResourceService } from '$lib/gen' + import { ResourceService, WorkspaceService } from '$lib/gen' import { globalDbManagerDrawer, workspaceStore } from '$lib/stores' import { onMount, untrack } from 'svelte' import AppConnect from './AppConnectDrawer.svelte' @@ -28,6 +28,7 @@ class?: string onClear?: () => void excludedValues?: string[] + datatableAsPgResource?: boolean } let { @@ -45,7 +46,8 @@ selectInputClass = '', class: className = '', onClear = undefined, - excludedValues = undefined + excludedValues = undefined, + datatableAsPgResource = false }: Props = $props() if (initialValue && value == undefined) { @@ -117,6 +119,23 @@ type: x.resource_type })) + if (datatableAsPgResource && resourceType === 'postgresql') { + try { + const datatables = await WorkspaceService.listDataTables({ + workspace: $workspaceStore! + }) + for (const dt of datatables) { + nc.push({ + value: `datatable://${dt}`, + label: `datatable://${dt}`, + type: 'postgresql' + }) + } + } catch (e) { + console.error('Failed to load data tables', e) + } + } + // TODO check if this is needed if (!nc.find((x) => x.value == value) && (initialValue || value)) { nc.push({ value: value ?? initialValue!, label: value ?? initialValue!, type: '' }) @@ -157,6 +176,7 @@ let resourceEditor: ResourceEditorDrawer | undefined = $state() let dbManagerDrawer = $derived(globalDbManagerDrawer.val) let hovering = $state(false) + let isDatatableSelected = $derived(value?.startsWith('datatable://') ?? false) {#snippet endSnippet({ item, close })} -
diff --git a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte index 4e3a1ab601..b69f3512af 100644 --- a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +++ b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte @@ -137,7 +137,8 @@ `GRANT CREATE ON DATABASE "${dbname}" TO custom_instance_user;\n` + 'ALTER DEFAULT PRIVILEGES IN SCHEMA public \n' + ' GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES\n TO custom_instance_user;\n' + - 'ALTER ROLE custom_instance_user CREATEROLE;' + 'ALTER ROLE custom_instance_user CREATEROLE;\n' + + 'ALTER ROLE custom_instance_user REPLICATION;' } ], status?.error ?? undefined diff --git a/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte b/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte index e92e8631bb..c7bedef359 100644 --- a/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte +++ b/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte @@ -51,7 +51,7 @@ } -