From eb3f8974e4c3310199b737cb78a5802ff5fed8d5 Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Tue, 24 Jun 2025 20:23:20 +0200 Subject: [PATCH 1/6] add vanta support to the server --- src/bin/server/config.rs | 8 + src/bin/server/db.rs | 8 + src/bin/server/main.rs | 10 + src/bin/server/vanta.rs | 445 +++++++++++++++++++++++++++++ src/bin/server/vanta_host_check.py | 78 +++++ 5 files changed, 549 insertions(+) create mode 100644 src/bin/server/vanta.rs create mode 100644 src/bin/server/vanta_host_check.py diff --git a/src/bin/server/config.rs b/src/bin/server/config.rs index d1254c82..16f0c230 100644 --- a/src/bin/server/config.rs +++ b/src/bin/server/config.rs @@ -19,6 +19,14 @@ pub struct Config { pub used_images_token: Option, #[serde(default)] pub status_token: Option, + #[serde(default)] + pub vanta_client_id: Option, + #[serde(default)] + pub vanta_client_secret: Option, + #[serde(default)] + pub vanta_users_resource: Option, + #[serde(default)] + pub vanta_hosts_resource: Option, } pub fn read_config() -> Result { diff --git a/src/bin/server/db.rs b/src/bin/server/db.rs index 83b7d0db..54047f3f 100644 --- a/src/bin/server/db.rs +++ b/src/bin/server/db.rs @@ -36,6 +36,14 @@ pub struct UserContent { pub password: String, #[serde(rename = "otp_base32")] pub otp_base32: String, + #[serde(default)] + pub first_name: Option, + #[serde(default)] + pub last_name: Option, + #[serde(default)] + pub email: Option, + #[serde(default)] + pub system: bool, } const USER_ID: i64 = 4; diff --git a/src/bin/server/main.rs b/src/bin/server/main.rs index 2f5635af..1df4e39b 100644 --- a/src/bin/server/main.rs +++ b/src/bin/server/main.rs @@ -36,6 +36,7 @@ mod ordered_json; mod setup; mod state; mod terminal; +mod vanta; mod variabels; mod web_util; mod webclient; @@ -44,6 +45,8 @@ use anyhow::Result; use clap::Parser; use webclient::run_web_clients; +use crate::vanta::run_vanta; + #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { @@ -124,6 +127,13 @@ async fn main() -> Result<()> { .shutdown_order(1) .create(|rt| run_web_clients(state.clone(), rt)); + if state.config.vanta_client_id.is_some() { + TaskBuilder::new("vanta_loop") + .main() + .shutdown_order(1) + .create(|rt| run_vanta(state.clone(), rt)); + } + TaskBuilder::new("user2") .main() .abort() diff --git a/src/bin/server/vanta.rs b/src/bin/server/vanta.rs new file mode 100644 index 00000000..c3df9dc3 --- /dev/null +++ b/src/bin/server/vanta.rs @@ -0,0 +1,445 @@ +use std::{sync::Arc, time::Duration}; + +use anyhow::{Context, Result, bail}; +use futures::future::join_all; +use log::{error, info}; +use sadmin2::{ + client_message::{ + ClientHostMessage, HostClientMessage, RunInstantMessage, RunInstantStdinOutputType, + RunInstantStdinType, + }, + type_types::{HOST_ID, USER_ID}, +}; +use serde::{Deserialize, Serialize}; +use sqlx::SqlitePool; +use sqlx_type::query; +use tokio::time::timeout; +use tokio_tasks::{RunToken, cancelable}; + +use crate::{config::Config, db::UserContent, state::State}; + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VantaUser { + display_name: String, + unique_id: String, + external_url: String, + full_name: String, + account_name: String, + email: String, + permission_level: &'static str, + created_timestamp: String, + status: &'static str, + mfa_enabled: bool, + mfa_methods: &'static [&'static str], + auth_method: &'static str, + updated_timestamp: String, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VantaUserAccounts { + resource_id: String, + resources: Vec, +} + +#[derive(Serialize, Debug)] +struct VantaTokenRequest<'a> { + client_id: &'a str, + client_secret: &'a str, + scope: &'a str, + grant_type: &'a str, +} + +#[derive(Deserialize, Debug)] +struct VantaTokenResponse { + access_token: String, +} + +#[derive(Deserialize, Debug)] +struct VantaSyncResponse { + success: bool, +} + +async fn push_users(config: &Config, db: &SqlitePool) -> Result<()> { + let Some(client_id) = &config.vanta_client_id else { + return Ok(()); + }; + let Some(client_secret) = &config.vanta_client_secret else { + return Ok(()); + }; + let Some(resource_id) = &config.vanta_users_resource else { + return Ok(()); + }; + let rows = query!( + "SELECT `id`, `name`, `content`, `time`, (SELECT MIN(`o2`.`time`) FROM `objects` AS `o2` WHERE `o2`.`id` = `o`.`id`) AS `created` + FROM `objects` AS `o` WHERE `type`=? AND `newest`=true", + USER_ID + ).fetch_all(db).await?; + + let mut resources = Vec::new(); + + for row in rows { + let content: UserContent = match serde_json::from_str(&row.content) { + Ok(v) => v, + Err(e) => { + error!( + "Error parsing user content of user {}({}): {:?}", + row.name, row.id, e + ); + continue; + } + }; + if content.system { + continue; + } + let Some(email) = content.email else { + continue; + }; + if !email.contains("@") { + error!("Invalid email '{}'", email); + continue; + } + resources.push(VantaUser { + display_name: row.name.clone(), + unique_id: row.id.to_string(), + external_url: format!( + "https://{}/?page=object&type=4&id={}", + config.hostname, row.id + ), + full_name: format!( + "{} {}", + content.first_name.as_deref().unwrap_or_default(), + content.last_name.as_deref().unwrap_or_default() + ), + account_name: row.name, + email, + permission_level: if content.admin { "ADMIN" } else { "BASE" }, + created_timestamp: row.created.unwrap().and_utc().to_rfc3339(), + status: "ACTIVE", + mfa_enabled: true, + mfa_methods: &["OTP"], + auth_method: "PASSWORD", + updated_timestamp: row.time.and_utc().to_rfc3339(), + }); + } + + let client = reqwest::Client::new(); + + let r = client + .post("https://api.vanta.com/oauth/token") + .json(&VantaTokenRequest { + client_id: client_id, + client_secret: client_secret, + scope: "connectors.self:write-resource", + grant_type: "client_credentials", + }) + .build() + .context("Failed building token request")?; + + let r = client + .execute(r) + .await + .context("Faild executing token request")?; + + if let Err(e) = r.error_for_status_ref() { + let text = r.text().await?; + return Err(e).context(format!("Faild executing token request: {}", text)); + } + + let token: VantaTokenResponse = r.json().await.context("Failed getting token")?; + let accounts = VantaUserAccounts { + resource_id: resource_id.clone(), + resources, + }; + + let request = client + .put("https://api.vanta.com/v1/resources/user_account") + .bearer_auth(token.access_token) + .json(&accounts) + .build() + .context("Failed building users request")?; + + let r = client + .execute(request) + .await + .context("Failed executing users request")?; + + if let Err(e) = r.error_for_status_ref() { + let text = r.text().await?; + return Err(e).context(format!("Failed executing users request: {}", text)); + } + + let response: VantaSyncResponse = r + .json() + .await + .context("Failed deserializing sync response")?; + + if !response.success { + bail!("Failed syncing vanta users"); + } + + info!("Successfully synced vanta users"); + Ok(()) +} + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "snake_case")] +enum Firewall { + NoUfwStatus, + Inactive, + Ok, + Dirty, +} + +#[derive(Deserialize, Debug)] +struct AnalyzeHostResult { + firewall: Firewall, + ufw_status: Option, + distribution: Option, + uname: Option, + data_encrypted: Option, + root_encrypted: Option, +} + +const VANTA_CHECK_SCRIPT: &str = include_str!("vanta_host_check.py"); + +#[derive(Serialize, Debug)] +#[serde(rename_all = "snake_case")] +enum HostStatus { + Ok, + HostDown, + Internal, + Timeout, + CommandFailed, + WrongMessage, + InvalidJson, +} + +async fn analyze_host(state: &State, id: i64) -> Result { + let host = state.host_clients.lock().unwrap().get(&id).cloned(); + let Some(host) = host else { + return Err(HostStatus::HostDown); + }; + + let mut jh = host + .start_job(&HostClientMessage::RunInstant(RunInstantMessage { + id: host.next_job_id(), + name: "vanta_check.py".into(), + interperter: "/usr/bin/python3".into(), + content: VANTA_CHECK_SCRIPT.to_string(), + args: Vec::new(), + output_type: RunInstantStdinOutputType::Json, + stdin_type: RunInstantStdinType::None, + })) + .await + .map_err(|_| HostStatus::Internal)?; + + match timeout(Duration::from_secs(60), jh.next_message()).await { + Err(_) => return Err(HostStatus::Timeout), + Ok(Err(_)) => return Err(HostStatus::HostDown), + Ok(Ok(Some(ClientHostMessage::Success(msg)))) => { + if let Some(code) = msg.code { + if code != 0 { + return Err(HostStatus::CommandFailed); + } + } + let Some(data) = msg.data else { + return Err(HostStatus::InvalidJson); + }; + let Ok(result) = serde_json::from_value::(data) else { + return Err(HostStatus::InvalidJson); + }; + return Ok(result); + } + Ok(Ok(Some(ClientHostMessage::Failure(_)))) => return Err(HostStatus::CommandFailed), + Ok(Ok(Some(_))) => return Err(HostStatus::WrongMessage), + Ok(Ok(None)) => return Err(HostStatus::HostDown), + } +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VantaHostResourceCustom { + category: String, + firewall: bool, + status: HostStatus, + ufw_status: Option, + distribution: Option, + uname: Option, + data_encrypted: Option, + root_encrypted: Option, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VantaHostResource { + display_name: String, + unique_id: String, + external_url: String, + custom_properties: VantaHostResourceCustom, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct VantaHostResources { + resource_id: String, + resources: Vec, +} + +pub async fn push_hosts(state: &State) -> Result<()> { + let config = &state.config; + let db = &state.db; + + let Some(client_id) = &config.vanta_client_id else { + return Ok(()); + }; + let Some(client_secret) = &config.vanta_client_secret else { + return Ok(()); + }; + let Some(resource_id) = &config.vanta_hosts_resource else { + return Ok(()); + }; + let rows = query!( + "SELECT `id`, `name`, `content`, `time`, `category` + FROM `objects` WHERE `type`=? AND `category` != 'Developer' AND `newest`=true", + HOST_ID + ) + .fetch_all(db) + .await?; + + info!("Starting {} analyzing host futures", rows.len()); + let mut futures = Vec::new(); + for row in &rows { + futures.push(analyze_host(state, row.id)); + } + let mut resources = Vec::new(); + let results = join_all(futures).await; + info!("Got all results"); + for (row, result) in rows.into_iter().zip(results) { + let (host_status, status) = match result { + Ok(v) => (Some(v), HostStatus::Ok), + Err(e) => (None, e), + }; + let external_url = format!( + "https://{}/?page=object&type=2&id={}", + config.hostname, row.id + ); + if let Some(host_status) = host_status { + resources.push(VantaHostResource { + display_name: row.name, + unique_id: row.id.to_string(), + external_url, + custom_properties: VantaHostResourceCustom { + category: row.category, + firewall: matches!(host_status.firewall, Firewall::Ok), + status, + ufw_status: host_status.ufw_status, + distribution: host_status.distribution, + uname: host_status.uname, + data_encrypted: host_status.data_encrypted, + root_encrypted: host_status.root_encrypted, + }, + }); + } else { + resources.push(VantaHostResource { + display_name: row.name, + unique_id: row.id.to_string(), + external_url, + custom_properties: VantaHostResourceCustom { + category: row.category, + firewall: false, + status: status, + ufw_status: None, + distribution: None, + uname: None, + data_encrypted: None, + root_encrypted: None, + }, + }); + } + } + + let client = reqwest::Client::new(); + + let r = client + .post("https://api.vanta.com/oauth/token") + .json(&VantaTokenRequest { + client_id: client_id, + client_secret: client_secret, + scope: "connectors.self:write-resource", + grant_type: "client_credentials", + }) + .build() + .context("Failed building token request")?; + + let r = client + .execute(r) + .await + .context("Faild executing token request")?; + + if let Err(e) = r.error_for_status_ref() { + let text = r.text().await?; + return Err(e).context(format!("Faild executing token request: {}", text)); + } + + let token: VantaTokenResponse = r.json().await.context("Failed getting token")?; + + let resources = VantaHostResources { + resource_id: resource_id.clone(), + resources, + }; + + let request = client + .put("https://api.vanta.com/v1/resources/custom_resource") + .bearer_auth(token.access_token) + .json(&resources) + .build() + .context("Failed building hosts request")?; + + let r = client + .execute(request) + .await + .context("Failed executing hosts request")?; + + if let Err(e) = r.error_for_status_ref() { + let text = r.text().await?; + return Err(e).context(format!("Failed executing hosts request: {}", text)); + } + + let response: VantaSyncResponse = r + .json() + .await + .context("Failed deserializing sync response")?; + + if !response.success { + bail!("Failed syncing vanta hosts"); + } + + info!("Successfully synced vanta hosts"); + + Ok(()) +} + +pub async fn run_vanta(state: Arc, run_token: RunToken) -> Result<()> { + loop { + if let Err(e) = push_users(&state.config, &state.db).await { + error!("Failed sending vanta users: {:?}", e); + } + + if let Err(e) = push_hosts(&state).await { + error!("Failed sending vanta hosts: {:?}", e); + } + + if cancelable( + &run_token, + tokio::time::sleep(Duration::from_secs(60 * 60 * 6)), + ) + .await + .is_err() + { + break; + } + } + Ok(()) +} diff --git a/src/bin/server/vanta_host_check.py b/src/bin/server/vanta_host_check.py new file mode 100644 index 00000000..855aea18 --- /dev/null +++ b/src/bin/server/vanta_host_check.py @@ -0,0 +1,78 @@ +import subprocess +import socket +import json +from typing import Any + +ufw_status: str | None = None +try: + ufw_status = subprocess.check_output(["ufw", "status"], encoding='utf-8') +except Exception as e: + firewall = "no_ufw_status" + ufw_status = None +else: + lines = iter(ufw_status.splitlines()) + if next(lines) != "Status: active": + firewall = "inactive" + else: + firewall = "ok" + next(lines) + next(lines) + next(lines) + for line in lines: + if not line: + continue + parts = line.rsplit(" # ", 1) + if len(parts) != 2 or not parts[1].startswith("simple_admin_"): + firewall = "dirty" + +distribution = None +with open("/etc/lsb-release", "r") as f: + for line in f: + lp = line.strip().split("=", 2) + match lp: + case ["DISTRIB_DESCRIPTION", s]: + distribution = s[1:-1] + +try: + uname = subprocess.check_output(["uname", "-a"], encoding='utf-8').strip() +except Exception as e: + uname = None + +data_encrypted: bool | None = None +root_encrypted: bool | None = None + +try: + lsblk_out = json.loads(subprocess.check_output(["/usr/bin/lsblk", "--json"], encoding='utf-8')) + def visit_block_dev(dev: Any, encrypted: bool) -> None: + global data_encrypted, root_encrypted + match dev["type"]: + case "lvm": + pass + case "crypt": + encrypted = True + case _: + encrypted = False + for mount_point in dev.get("mountpoints", []): + match mount_point: + case "/": + root_encrypted = encrypted + case "/data": + data_encrypted = encrypted + for child in dev.get("children", []): + visit_block_dev(child, encrypted) + for dev in lsblk_out['blockdevices']: + visit_block_dev(dev, False) +except Exception as e: + pass + + +status = { + "firewall": firewall, + "hostname": socket.gethostname(), + "ufw_status": ufw_status, + "distribution": distribution, + "uname": uname, + "data_encrypted": data_encrypted, + "root_encrypted": root_encrypted, +} +print(json.dumps(status, indent=2)) \ No newline at end of file From 73af2aa364a62b439f13c53e9ad3777e60c8cf9c Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Wed, 2 Jul 2025 08:40:19 +0200 Subject: [PATCH 2/6] server: Handle command spwan errors --- src/bin/server/webclient.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/server/webclient.rs b/src/bin/server/webclient.rs index 7c946793..157b45a8 100644 --- a/src/bin/server/webclient.rs +++ b/src/bin/server/webclient.rs @@ -743,6 +743,7 @@ impl WebClient { .unwrap() .remove(&command_id); } + r??; Ok(()) } From 804813c2da6e5f2816fbaaa975c61dc1e85655fc Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Wed, 2 Jul 2025 08:50:28 +0200 Subject: [PATCH 3/6] update dependencies --- Cargo.lock | 340 ++++++++++++++++++++--------------- Cargo.toml | 4 +- frontend/src/shared_types.ts | 58 +++++- src/action_types.rs | 20 ++- src/finite_float.rs | 1 + src/page_types.rs | 6 +- src/type_types.rs | 5 +- 7 files changed, 268 insertions(+), 166 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b126cfb4..279969fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -76,33 +76,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.8" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" @@ -202,7 +202,7 @@ dependencies = [ "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.26.2", "tower", "tower-layer", "tower-service", @@ -256,9 +256,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bindgen" @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -327,9 +327,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.25" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -347,9 +347,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -396,9 +396,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -406,9 +406,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -418,9 +418,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -430,9 +430,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "cmake" @@ -445,9 +445,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "concurrent-queue" @@ -460,15 +460,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.11" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.0", - "windows-sys 0.59.0", + "unicode-width 0.2.1", + "windows-sys 0.60.2", ] [[package]] @@ -605,7 +605,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -654,12 +654,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -704,9 +704,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "libz-rs-sys", @@ -870,7 +870,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -911,9 +911,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", "equivalent", @@ -935,7 +935,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.3", + "hashbrown 0.15.4", ] [[package]] @@ -1045,9 +1045,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.6" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ "http", "hyper", @@ -1057,14 +1057,14 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] name = "hyper-util" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" dependencies = [ "base64", "bytes", @@ -1217,27 +1217,38 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", ] [[package]] name = "indicatif" -version = "0.17.11" +version = "0.17.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +checksum = "4adb2ee6ad319a912210a36e56e3623555817bcc877a7e6e8802d1d69c4d8056" dependencies = [ "console", - "number_prefix", "portable-atomic", - "unicode-width 0.2.0", + "unicode-width 0.2.1", + "unit-prefix", "web-time", ] +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "libc", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -1321,9 +1332,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" @@ -1332,7 +1343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.0", + "windows-targets 0.53.2", ] [[package]] @@ -1343,9 +1354,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ "bitflags 2.9.1", "libc", @@ -1364,9 +1375,9 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a" +checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" dependencies = [ "zlib-rs", ] @@ -1429,9 +1440,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memoffset" @@ -1456,9 +1467,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -1470,7 +1481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -1555,12 +1566,6 @@ dependencies = [ "libm", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[package]] name = "object" version = "0.36.7" @@ -1682,9 +1687,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" @@ -1706,9 +1711,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.33" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", "syn", @@ -1766,9 +1771,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" dependencies = [ "cfg_aliases", "libc", @@ -1789,9 +1794,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -1854,9 +1859,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags 2.9.1", ] @@ -1903,9 +1908,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.18" +version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ "base64", "bytes", @@ -1916,11 +1921,8 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", @@ -1939,7 +1941,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] @@ -2013,9 +2015,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -2057,9 +2059,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "aws-lc-rs", "log", @@ -2148,13 +2150,13 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-tasks", - "tokio-tungstenite", + "tokio-tungstenite 0.27.0", "tokio-util", "totp-rs", "ts-rs", "uuid", "webpki", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", "zip", ] @@ -2314,18 +2316,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" dependencies = [ "serde", ] @@ -2367,9 +2366,9 @@ checksum = "df31f2e28a3418618bdaf29ee3547e596ca13ca08d9481418e436c6e9f763ed6" [[package]] name = "sql-type" -version = "0.24.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9ac66b079c06d420fc409f014c21a665dba06bfa471edf1ddfcbf92abcbeb1" +checksum = "d764260f72976be30b77e5dab310ba87a02cb43bdfb9c06e021a5a6140edb296" dependencies = [ "sql-parse", ] @@ -2404,7 +2403,7 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "hashlink 0.10.0", "indexmap", "log", @@ -2568,9 +2567,9 @@ dependencies = [ [[package]] name = "sqlx-type" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c02a3496cce874f317854b66d955427f0d4ace6bbed8ffe3a7680584469d3f9" +checksum = "91f78caf9dd1dea4f1d834184807046ec18a598a1141a568150a2dd4a848a005" dependencies = [ "chrono", "sqlx-type-macro", @@ -2578,9 +2577,9 @@ dependencies = [ [[package]] name = "sqlx-type-macro" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab615838864348826934adcd737d16e7506dbdd5b99d8bbb118ac449602b765" +checksum = "1e23c4be582a7078bbbbf005e6bc76fc7a0f6ec5fe585085f92144705d19328b" dependencies = [ "ariadne", "once_cell", @@ -2623,9 +2622,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -2721,16 +2720,18 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.45.1" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "pin-project-lite", "signal-hook-registry", + "slab", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -2785,6 +2786,18 @@ name = "tokio-tungstenite" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.26.2", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" dependencies = [ "futures-util", "log", @@ -2792,7 +2805,7 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite", + "tungstenite 0.27.0", "webpki-roots 0.26.11", ] @@ -2841,9 +2854,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.9.1", "bytes", @@ -2883,9 +2896,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", @@ -2894,9 +2907,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -2909,13 +2922,12 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ts-rs" -version = "10.1.0" +version = "11.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e640d9b0964e9d39df633548591090ab92f7a4567bc31d3891af23471a3365c6" +checksum = "6ef1b7a6d914a34127ed8e1fa927eb7088903787bcded4fa3eef8f85ee1568be" dependencies = [ "chrono", "indexmap", - "lazy_static", "serde_json", "thiserror", "ts-rs-macros", @@ -2923,9 +2935,9 @@ dependencies = [ [[package]] name = "ts-rs-macros" -version = "10.1.0" +version = "11.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9d8656589772eeec2cf7a8264d9cda40fb28b9bc53118ceb9e8c07f8f38730" +checksum = "e9d4ed7b4c18cc150a6a0a1e9ea1ecfa688791220781af6e119f9599a8502a0a" dependencies = [ "proc-macro2", "quote", @@ -2938,6 +2950,23 @@ name = "tungstenite" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.1", + "sha1", + "thiserror", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" dependencies = [ "bytes", "data-encoding", @@ -2993,9 +3022,15 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" + +[[package]] +name = "unit-prefix" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" [[package]] name = "unsafe-libyaml" @@ -3079,9 +3114,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -3205,14 +3240,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] name = "webpki-roots" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -3285,9 +3320,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-result" @@ -3334,6 +3369,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -3367,9 +3411,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", @@ -3566,18 +3610,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", @@ -3646,9 +3690,9 @@ dependencies = [ [[package]] name = "zip" -version = "4.0.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "153a6fff49d264c4babdcfa6b4d534747f520e56e8f0f384f3b808c4b64cc1fd" +checksum = "95ab361742de920c5535880f89bbd611ee62002bf11341d16a5f057bb8ba6899" dependencies = [ "arbitrary", "crc32fast", @@ -3660,9 +3704,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8" +checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index 108d8935..2f4746be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,10 +80,10 @@ tempfile = {version="3", optional=true} tokio = { version = "1", default-features = false, features=['rt', 'net', 'fs', 'sync', 'macros', 'time', 'process', 'signal', 'io-std', 'rt-multi-thread'] } tokio-rustls = "0.26" tokio-tasks = {version = "0.2", optional=true} -tokio-tungstenite = { version = "0.26", features=['rustls-tls-webpki-roots']} +tokio-tungstenite = { version = "0.27", features=['rustls-tls-webpki-roots']} tokio-util = {version = "0.7", features = ["io"], optional = true} totp-rs= {version="5", features = ["otpauth"], optional = true} -ts-rs = {version="10", features = ["serde-compat", "chrono-impl", "serde-json-impl", "no-serde-warnings", "indexmap-impl"]} +ts-rs = {version="11", features = ["serde-compat", "chrono-impl", "serde-json-impl", "no-serde-warnings", "indexmap-impl"]} uuid = {version="1", features = ["v4", "serde"], optional = true} webpki = "0.22" webpki-roots = "1" diff --git a/frontend/src/shared_types.ts b/frontend/src/shared_types.ts index 1d8c5bea..8256df87 100644 --- a/frontend/src/shared_types.ts +++ b/frontend/src/shared_types.ts @@ -284,7 +284,7 @@ export type IStartLog = { host: number; logtype: IStartLogLogType; id: number; - unit: string | null; + unit?: string | null; }; export type IEndLog = { host: number; id: number }; @@ -299,7 +299,7 @@ export type IAddMessage = { message: IMessage }; export type ISetMessagesDismissed = { ids: Array; dismissed: boolean; source: ISource }; -export type ISaveObject = { id: number; obj: IObject2<{ [key in string]?: JsonValue }> | null }; +export type ISaveObject = { id: number; obj?: IObject2<{ [key in string]?: JsonValue }> | null }; export type ISearch = { ref: Ref; pattern: string }; @@ -551,6 +551,10 @@ export type IRunCommandOutput = { id: number; stdout?: string; stderr?: string } export type IRunCommandFinished = { id: number; status: number }; +export type IGetSecret = { name: string; host: string | null }; + +export type IGetSecretRes = { ref: Ref; id: number | null }; + export type IServerAction = | ({ type: "AddDeploymentLog" } & IAddDeploymentLog) | ({ type: "AddMessage" } & IAddMessage) @@ -584,7 +588,13 @@ export type IServerAction = | ({ type: "SetInitialState" } & ISetInitialState) | ({ type: "SetMessagesDismissed" } & ISetMessagesDismissed) | ({ type: "SetPage" } & ISetPageAction) - | ({ type: "ToggleDeploymentObject" } & IToggleDeploymentObject); + | ({ type: "ToggleDeploymentObject" } & IToggleDeploymentObject) + | ({ type: "GetSecretRes" } & IGetSecretRes) + | ({ type: "Response" } & IResponse) + | ({ type: "SocketRecv" } & ISocketRecv) + | ({ type: "CommandStdout" } & ICommandStdout) + | ({ type: "CommandStderr" } & ICommandStderr) + | ({ type: "CommandFinished" } & ICommandFinished); export type IClientAction = | ({ type: "CancelDeployment" } & ICancelDeployment) @@ -622,4 +632,44 @@ export type IClientAction = | ({ type: "SetMessageDismissed" } & ISetMessagesDismissed) | ({ type: "StartDeployment" } & IStartDeployment) | ({ type: "StopDeployment" } & IStopDeployment) - | ({ type: "ToggleDeploymentObject" } & IToggleDeploymentObject); + | ({ type: "ToggleDeploymentObject" } & IToggleDeploymentObject) + | ({ type: "GetSecret" } & IGetSecret) + | ({ type: "SocketConnect" } & ISocketConnect) + | ({ type: "SocketClose" } & ISocketClose) + | ({ type: "SocketSend" } & ISocketSend) + | ({ type: "CommandSpawn" } & ICommandSpawn) + | ({ type: "CommandStdin" } & ICommandStdin) + | ({ type: "CommandSignal" } & ICommandSignal); + +export type IResponse = { msg_id: number; error: string | null }; + +export type ISocketConnect = { msg_id: number; socket_id: number; host: string; dst: string }; + +export type ISocketClose = { msg_id: number; socket_id: number }; + +export type ISocketSend = { msg_id: number; socket_id: number; data: string | null }; + +export type ICommandSpawn = { + msg_id: number; + command_id: number; + host: string; + program: string; + args: Array; + forward_stdin: boolean; + forward_stdout: boolean; + forward_stderr: boolean; + env: { [key in string]?: string } | null; + cwd: string | null; +}; + +export type ICommandStdin = { msg_id: number; command_id: number; data: string | null }; + +export type ICommandSignal = { msg_id: number; command_id: number; signal: number }; + +export type ISocketRecv = { socket_id: number; data: string | null }; + +export type ICommandStdout = { command_id: number; data: string | null }; + +export type ICommandStderr = { command_id: number; data: string | null }; + +export type ICommandFinished = { command_id: number; code: number; signal: number | null }; diff --git a/src/action_types.rs b/src/action_types.rs index 06f213e8..79a8e16b 100644 --- a/src/action_types.rs +++ b/src/action_types.rs @@ -35,6 +35,7 @@ pub enum DeploymentStatus { impl TS for DeploymentStatus { type WithoutGenerics = DeploymentStatus; + type OptionInnerType = Self; fn name() -> String { "DEPLOYMENT_STATUS".to_owned() } @@ -59,8 +60,8 @@ impl TS for DeploymentStatus { fn inline_flattened() -> String { todo!(); } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("DeploymentStatus.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("DeploymentStatus.ts")) } } @@ -75,6 +76,7 @@ pub enum DeploymentObjectStatus { impl TS for DeploymentObjectStatus { type WithoutGenerics = DeploymentStatus; + type OptionInnerType = Self; fn name() -> String { "DEPLOYMENT_OBJECT_STATUS".to_owned() } @@ -96,8 +98,8 @@ impl TS for DeploymentObjectStatus { fn inline_flattened() -> String { todo!(); } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("DeploymentObjectStatus.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("DeploymentObjectStatus.ts")) } } @@ -112,6 +114,7 @@ pub enum DeploymentObjectAction { impl TS for DeploymentObjectAction { type WithoutGenerics = DeploymentStatus; + type OptionInnerType = Self; fn name() -> String { "DEPLOYMENT_OBJECT_ACTION".to_owned() } @@ -133,8 +136,8 @@ impl TS for DeploymentObjectAction { fn inline_flattened() -> String { todo!(); } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("DeploymentObjectAction.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("DeploymentObjectAction.ts")) } } @@ -369,6 +372,7 @@ pub enum ObjectType { impl ::ts_rs::TS for ObjectType { type WithoutGenerics = ObjectType; + type OptionInnerType = Self; fn name() -> String { "ObjectType".to_owned() } @@ -384,8 +388,8 @@ impl ::ts_rs::TS for ObjectType { fn inline_flattened() -> String { todo!() } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("ObjectType.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("ObjectType.ts")) } } diff --git a/src/finite_float.rs b/src/finite_float.rs index 5bacd626..5664b953 100644 --- a/src/finite_float.rs +++ b/src/finite_float.rs @@ -97,6 +97,7 @@ impl Ord for FiniteF64 { impl TS for FiniteF64 { type WithoutGenerics = Self; + type OptionInnerType = Self; fn decl() -> String { panic!("FiniteF64 cannot be declared") diff --git a/src/page_types.rs b/src/page_types.rs index ed826a87..835136bc 100644 --- a/src/page_types.rs +++ b/src/page_types.rs @@ -73,6 +73,8 @@ pub enum IPage { } impl ::ts_rs::TS for IPage { type WithoutGenerics = IPage; + type OptionInnerType = Self; + fn ident() -> String { "IPage".to_owned() } @@ -113,8 +115,8 @@ impl ::ts_rs::TS for IPage { { } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("IPage.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("IPage.ts")) } fn visit_dependencies(_: &mut impl ::ts_rs::TypeVisitor) diff --git a/src/type_types.rs b/src/type_types.rs index e50b30b2..68e2b414 100644 --- a/src/type_types.rs +++ b/src/type_types.rs @@ -119,6 +119,7 @@ pub enum ITypeProp { impl TS for ITypeProp { type WithoutGenerics = ITypeProp; + type OptionInnerType = Self; fn ident() -> String { "ITypeProp".to_owned() } @@ -146,8 +147,8 @@ impl TS for ITypeProp { fn inline_flattened() -> String { todo!() } - fn output_path() -> Option<&'static std::path::Path> { - Some(std::path::Path::new("ITypeProp.ts")) + fn output_path() -> Option { + Some(std::path::PathBuf::from("ITypeProp.ts")) } fn visit_dependencies(_: &mut impl ::ts_rs::TypeVisitor) where From cacf4e34a299dcdefa2bcb5b4b36f018fba6e614 Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Wed, 2 Jul 2025 09:54:20 +0200 Subject: [PATCH 4/6] fix issues pointed out by clippy --- src/action_types.rs | 4 +- src/bin/export_ts.rs | 8 ++-- src/bin/sadmin/client_daemon.rs | 55 ++++++++++++------------- src/bin/sadmin/client_daemon_service.rs | 21 +++++----- src/bin/sadmin/main.rs | 2 +- src/bin/sadmin/persist_daemon.rs | 14 +++---- src/bin/sadmin/port.rs | 4 +- src/bin/sadmin/run.rs | 5 +-- src/bin/server/crt.rs | 10 ++--- src/bin/server/db.rs | 6 +-- src/bin/server/deployment.rs | 43 +++++++++---------- src/bin/server/docker.rs | 40 +++++++----------- src/bin/server/docker_web.rs | 23 +++++------ src/bin/server/hostclient.rs | 32 +++++++------- src/bin/server/modified_files.rs | 14 +++---- src/bin/server/vanta.rs | 36 ++++++++-------- src/bin/server/webclient.rs | 26 ++++++------ src/page_types.rs | 2 +- src/type_types.rs | 2 +- 19 files changed, 163 insertions(+), 184 deletions(-) diff --git a/src/action_types.rs b/src/action_types.rs index 79a8e16b..8eb22ec0 100644 --- a/src/action_types.rs +++ b/src/action_types.rs @@ -417,7 +417,7 @@ impl<'de> Deserialize<'de> for ObjectType { v => { let v = v .parse() - .map_err(|_| E::custom(format!("Invalid object type '{}'", v)))?; + .map_err(|_| E::custom(format!("Invalid object type '{v}'")))?; Ok(ObjectType::Id(v)) } } @@ -435,7 +435,7 @@ impl<'de> Deserialize<'de> for ObjectType { E: serde::de::Error, { Ok(ObjectType::Id(v.try_into().map_err(|_| { - E::custom(format!("Invalid object type {}", v)) + E::custom(format!("Invalid object type {v}")) })?)) } } diff --git a/src/bin/export_ts.rs b/src/bin/export_ts.rs index 649cd21b..e4142b72 100644 --- a/src/bin/export_ts.rs +++ b/src/bin/export_ts.rs @@ -83,16 +83,16 @@ pub fn main() -> Result<()> { }; let new_actions = output.stdout; - let actions = std::fs::read(p).with_context(|| format!("Failed reading {}", p))?; + let actions = std::fs::read(p).with_context(|| format!("Failed reading {p}"))?; if actions != new_actions { if args.validate { bail!("{} is not up to date", p); } else { - println!("{} generated", p); - std::fs::write(p, &new_actions).with_context(|| format!("Failed writing {}", p))? + println!("{p} generated"); + std::fs::write(p, &new_actions).with_context(|| format!("Failed writing {p}"))? } } else { - println!("{} is up to date", p); + println!("{p} is up to date"); } Ok(()) } diff --git a/src/bin/sadmin/client_daemon.rs b/src/bin/sadmin/client_daemon.rs index 9fb9a00f..a6d44084 100644 --- a/src/bin/sadmin/client_daemon.rs +++ b/src/bin/sadmin/client_daemon.rs @@ -171,7 +171,7 @@ impl Client { val = write_all => { if let Err(e) = val { // The send errored out, notify the recv half so we can try to initiate a new connection - error!("Failed sending message to backend: {}", e); + error!("Failed sending message to backend: {e}"); self.send_failure_notify.notify_one(); *s = None } @@ -195,7 +195,7 @@ impl Client { } async fn handle_ping(self: Arc, id: u64) { - debug!("Ping from server {}", id); + debug!("Ping from server {id}"); self.send_message(ClientHostMessage::Pong { id }).await; } @@ -230,8 +230,8 @@ impl Client { "Instant command failed {} failed with code {:?}", msg.id, code ); - debug!("stdout: '{}'", stdout); - debug!("stderr: '{}'", stderr); + debug!("stdout: '{stdout}'"); + debug!("stderr: '{stderr}'"); return Ok(ClientHostMessage::Failure(FailureMessage { id: msg.id, code, @@ -267,7 +267,7 @@ impl Client { let m = match self.handle_run_instant_inner(&run_token, msg).await { Ok(v) => v, Err(e) => { - error!("Error in instant command {}: {}", id, e); + error!("Error in instant command {id}: {e}"); ClientHostMessage::Failure(FailureMessage { id, failure_type: Some(FailureType::Exception), @@ -280,7 +280,7 @@ impl Client { self.send_message(m).await; run_token.set_location(file!(), line!()); self.command_tasks.lock().unwrap().remove(&id); - debug!("Finished instant command {}", id); + debug!("Finished instant command {id}"); Ok(()) } @@ -522,7 +522,7 @@ impl Client { self.send_message(m).await; self.command_tasks.lock().unwrap().remove(&id); self.script_stdin.lock().unwrap().remove(&id); - debug!("Finished run script {}", id); + debug!("Finished run script {id}"); Ok(()) } @@ -583,7 +583,7 @@ impl Client { let m = match self.handle_deploy_service_inner(msg).await { Ok(m) => m, Err(e) => { - error!("Error in deploy service: {:?}", e); + error!("Error in deploy service: {e:?}"); self.send_message(ClientHostMessage::Data(DataMessage { id, source: Some(DataSource::Stderr), @@ -632,7 +632,7 @@ impl Client { self.send_message(ClientHostMessage::Failure(FailureMessage { id, failure_type: Some(FailureType::UnknownTask), - message: Some(format!("Unable to read file {}: {:?}", path, e)), + message: Some(format!("Unable to read file {path}: {e:?}")), ..Default::default() })) .await; @@ -674,7 +674,7 @@ impl Client { self.send_message(ClientHostMessage::Failure(FailureMessage { id, failure_type: Some(FailureType::UnknownTask), - message: Some(format!("Unable to write file {}: {:?}", path, e)), + message: Some(format!("Unable to write file {path}: {e:?}")), ..Default::default() })) .await; @@ -694,7 +694,7 @@ impl Client { Err(e) => { self.send_message(ClientHostMessage::Failure(FailureMessage { id, - message: Some(format!("{:?}", e)), + message: Some(format!("{e:?}")), ..Default::default() })) .await; @@ -751,18 +751,18 @@ impl Client { let (r, w) = if dst.contains(':') && !dst.contains("/") { let s = tokio::net::TcpStream::connect(&dst) .await - .with_context(|| format!("Unable to connect to {}", dst))?; + .with_context(|| format!("Unable to connect to {dst}"))?; let (r, w) = s.into_split(); (SocketRead::Tcp(r), SocketWrite::Tcp(w)) } else { let s = tokio::net::UnixStream::connect(&dst) .await - .with_context(|| format!("Unable to connect to {}", dst))?; + .with_context(|| format!("Unable to connect to {dst}"))?; let (r, w) = s.into_split(); (SocketRead::Unix(r), SocketWrite::Unix(w)) }; let s2 = self.clone(); - let task = TaskBuilder::new(format!("handle_tcp_socket_{}", socket_id)) + let task = TaskBuilder::new(format!("handle_tcp_socket_{socket_id}")) .shutdown_order(-99) .create(|rt| async move { s2.handle_socket(socket_id, rt, r).await }); @@ -787,7 +787,7 @@ impl Client { .lock() .unwrap() .remove(&socket_id) - .with_context(|| format!("Unknown socket {}", socket_id))?; + .with_context(|| format!("Unknown socket {socket_id}"))?; conn.task.run_token().cancel(); if let Err(e) = conn.task.clone().wait().await { match e { @@ -814,7 +814,7 @@ impl Client { .lock() .unwrap() .get(&socket_id) - .with_context(|| format!("Unknown socket {}", socket_id))? + .with_context(|| format!("Unknown socket {socket_id}"))? .clone(); if let Some(data) = data { let mut conn = conn.write.lock().await; @@ -1288,7 +1288,7 @@ impl Client { } pub async fn persist_close_fd(&self, key: &str, loc: &str) -> Result<()> { - info!("persist_close_fd {} @ {}", key, loc); + info!("persist_close_fd {key} @ {loc}"); self.send_persist_request_success( persist_daemon::Message::CloseFd { id: self.next_persist_idc(), @@ -1405,7 +1405,7 @@ impl Client { read } Ok(Ok(Err(e))) => { - info!("Error connecting to upstream: {:?}", e); + info!("Error connecting to upstream: {e:?}"); if let Some(notifier) = ¬ifier { if first { notifier.notify_ready()?; @@ -1455,7 +1455,7 @@ impl Client { } Ok(_) => {} Err(e) => { - error!("Failure reading from server: {}", e); + error!("Failure reading from server: {e}"); break } } @@ -1558,7 +1558,7 @@ impl Client { Err(_) => return Ok(()), }; if let persist_daemon::Message::ProcessDied { key, code } = message { - info!("Process died {}: {}", key, code); + info!("Process died {key}: {code}"); if let Some(send) = self.dead_process_handlers.lock().unwrap().remove(&key) { let _ = send.send(code); } @@ -1757,7 +1757,7 @@ impl Client { .handle_control_client_inner(&run_token, &mut socket) .await { - error!("Error in handle control client: {:?}", e); + error!("Error in handle control client: {e:?}"); Self::send_daemon_control_message( &mut socket, DaemonControlMessage::Stderr { @@ -1895,7 +1895,7 @@ async fn connect_to_persist(retry: usize) -> Result { bail!("Unable to connect to persist daemon: {}", e); } i += 1; - warn!("Unable to connect to persist daemon: {}, retry", e); + warn!("Unable to connect to persist daemon: {e}, retry"); tokio::time::sleep(Duration::from_millis(10)).await; } } @@ -1979,12 +1979,12 @@ async fn handle_usr2(client: Arc) -> Result<()> { info!("Script stdin:"); for k in client.script_stdin.lock().unwrap().keys() { - info!(" {}", k); + info!(" {k}"); } info!("persist_responses:"); for k in client.persist_responses.lock().unwrap().keys() { - info!(" {}", k); + info!(" {k}"); } info!("Command_tasks:"); @@ -1994,12 +1994,12 @@ async fn handle_usr2(client: Arc) -> Result<()> { info!("dead_process_handlers:"); for k in client.dead_process_handlers.lock().unwrap().keys() { - info!(" {}", k); + info!(" {k}"); } info!("services:"); for (k, v) in client.services.lock().unwrap().iter() { - info!(" {}:", k); + info!(" {k}:"); v.debug(); } } @@ -2055,8 +2055,7 @@ pub async fn client_daemon(config: Config, args: ClientDaemon) -> Result<()> { format!("Could not find '{auth_path}', so we expect a password in the config file") })?; warn!( - "Having the password in the config file is insecure, consider moving it to '{}'", - auth_path + "Having the password in the config file is insecure, consider moving it to '{auth_path}'" ); (password, None) } diff --git a/src/bin/sadmin/client_daemon_service.rs b/src/bin/sadmin/client_daemon_service.rs index 19c3bad8..63dcb767 100644 --- a/src/bin/sadmin/client_daemon_service.rs +++ b/src/bin/sadmin/client_daemon_service.rs @@ -1098,7 +1098,7 @@ impl Service { .status() .await?; if !status.success() { - error!("Failed running podman kill {}", status); + error!("Failed running podman kill {status}"); log.stdout(b"Failed running podman kill").await?; } } else { @@ -2299,17 +2299,16 @@ It will be hard killed in {:?} if it does not stop before that. ", .await { Ok(e) if e.success() => {} - Ok(e) => warn!("Failed running podman kill {}", e), - Err(e) => warn!("Failed running podman kill {}", e), + Ok(e) => warn!("Failed running podman kill {e}"), + Err(e) => warn!("Failed running podman kill {e}"), } } } - Ok((status, Ok(_))) => warn!("Failed running podman container ls status: {}", status), - Ok((status, Err(e))) => warn!( - "Failed running podman container ls status: {}, invalid output: {}", - status, e - ), - Err(e) => warn!("Failed running podman container ls {}", e), + Ok((status, Ok(_))) => warn!("Failed running podman container ls status: {status}"), + Ok((status, Err(e))) => { + warn!("Failed running podman container ls status: {status}, invalid output: {e}") + } + Err(e) => warn!("Failed running podman container ls {e}"), }; let _ = std::fs::remove_dir_all(format!("/run/simpleadmin/services/{}", self.name)); Ok(()) @@ -2373,7 +2372,7 @@ It will be hard killed in {:?} if it does not stop before that. ", port, path, }) => { - let response = reqwest::get(format!("http://127.0.0.1:{}{}", port, path)).await?; + let response = reqwest::get(format!("http://127.0.0.1:{port}{path}")).await?; if !response.status().is_success() { error!( "Failure to get status from {} {}: {}", @@ -2403,7 +2402,7 @@ It will be hard killed in {:?} if it does not stop before that. ", properties.push(("instance", &instance)); } } - writeln!(&mut res, "{}", line)?; + writeln!(&mut res, "{line}")?; } let start_time = start_time .duration_since(std::time::UNIX_EPOCH)? diff --git a/src/bin/sadmin/main.rs b/src/bin/sadmin/main.rs index eccc8f2e..3a66c35c 100644 --- a/src/bin/sadmin/main.rs +++ b/src/bin/sadmin/main.rs @@ -160,7 +160,7 @@ async fn get_secret(config: Config, args: GetSecret) -> Result<()> { if let IServerAction::GetSecretRes(r) = con.recv().await? { if r.name == args.secret { if let Some(v) = r.value { - println!("{}", v); + println!("{v}"); return Ok(()); } else { bail!("Secret {} not found", args.secret); diff --git a/src/bin/sadmin/persist_daemon.rs b/src/bin/sadmin/persist_daemon.rs index 17e81013..352a06a2 100644 --- a/src/bin/sadmin/persist_daemon.rs +++ b/src/bin/sadmin/persist_daemon.rs @@ -166,14 +166,14 @@ impl State { async fn handle_process(self: Arc, key: String, mut child: tokio::process::Child) { let ret = child.wait().await; - info!("Child process {} finished {:?}", key, ret); + info!("Child process {key} finished {ret:?}"); self.processes.lock().unwrap().remove(&key); let cons: Vec<_> = self.connections.lock().unwrap().values().cloned().collect(); let code = match ret { Err(_) => -99, Ok(v) => v.into_raw(), }; - info!("Child process {} finished with code: {}", key, code); + info!("Child process {key} finished with code: {code}"); for con in cons { let _ = Self::send_message( &con, @@ -246,7 +246,7 @@ impl State { Ok(()) }); } - info!("Spawning {:?}", cmd); + info!("Spawning {cmd:?}"); let child = cmd.spawn().context("Unable to spawn")?; let pid = child.id().context("Expected pid")?; info!("Started process key {}, pid {}", sp.key, pid); @@ -384,7 +384,7 @@ impl State { ) { let id = message.id(); if let Err(e) = self.handle_client_message_inner(message, &stream, fd).await { - error!("Error in handle_client_message info for message: {:?}", e); + error!("Error in handle_client_message info for message: {e:?}"); if let Err(e) = Self::send_message( &stream, Message::Error { @@ -395,7 +395,7 @@ impl State { ) .await { - error!("Failed to write to stream: {}", e); + error!("Failed to write to stream: {e}"); } } } @@ -462,7 +462,7 @@ impl State { ) .with_context(|| format!("Unable to chmod {path:?}"))?; - info!("Listining on {:?}", path); + info!("Listining on {path:?}"); if let Ok(notifier) = sdnotify::SdNotify::from_env() { notifier.notify_ready()?; @@ -477,7 +477,7 @@ impl State { tokio::spawn(self.clone().handle_client(stream, connection_id)); } Err(e) => { - error!("Failed to accept connection {}", e); + error!("Failed to accept connection {e}"); } } } diff --git a/src/bin/sadmin/port.rs b/src/bin/sadmin/port.rs index 5e9d8129..4fb90e57 100644 --- a/src/bin/sadmin/port.rs +++ b/src/bin/sadmin/port.rs @@ -82,7 +82,7 @@ pub async fn handle_socket( ) { if let Err(e) = handle_socket_inner(socket_read, send, socket_id, cmd, writer_shutdown_s).await { - eprintln!("Error in handle socket inner {:?}", e); + eprintln!("Error in handle socket inner {e:?}"); } } @@ -117,7 +117,7 @@ pub async fn proxy(config: Config, cmd: ProxySocket) -> Result<()> { let (socket_read, socket_write) = socket.into_split(); socket_write_halfs.insert(socket_id, socket_write); tokio::task::spawn(handle_socket(socket_read, send.clone(), socket_id, cmd, writer_shutdown_s.clone())); - println!("Accepting proxy connection from {:?}", addr); + println!("Accepting proxy connection from {addr:?}"); } r = recv.recv() => { match r? { diff --git a/src/bin/sadmin/run.rs b/src/bin/sadmin/run.rs index 05bb99e0..ee4bb7d5 100644 --- a/src/bin/sadmin/run.rs +++ b/src/bin/sadmin/run.rs @@ -119,8 +119,7 @@ pub async fn shell(config: Config, args: Shell) -> Result<()> { let (mut send, mut recv) = connect(config, args.host, lines, cols).await?.split(); send.send(tungstenite::Message::text(format!( - "dexport LINES={} COLUMNS={}\n\0", - lines, cols + "dexport LINES={lines} COLUMNS={cols}\n\0" ))) .await?; @@ -322,7 +321,7 @@ pub async fn run(config: Config, args: Run) -> Result<()> { ConnectionRecvRes::Message(IServerAction::CommandFinished(a)) => { if let Some(signal) = a.signal { if signal != 2 || do_process_ctrl_c { - eprintln!("Command finished with signal: {}", signal); + eprintln!("Command finished with signal: {signal}"); } } std::process::exit(a.code); diff --git a/src/bin/server/crt.rs b/src/bin/server/crt.rs index 799c2765..ffe61b85 100644 --- a/src/bin/server/crt.rs +++ b/src/bin/server/crt.rs @@ -73,8 +73,7 @@ pub async fn generate_srs(key: &str, cn: &str) -> Result { let mut t1 = NamedTempFile::new()?; write!( &mut t1, - "[req]\nprompt = no\ndistinguished_name = distinguished_name\n[distinguished_name]\nCN={}\n", - cn + "[req]\nprompt = no\ndistinguished_name = distinguished_name\n[distinguished_name]\nCN={cn}\n" )?; let mut t2 = NamedTempFile::new()?; t2.write_all(key.as_bytes())?; @@ -129,7 +128,7 @@ keyUsage = critical, keyCertSign, cRLSign, digitalSignature, nonRepudiation, key subjectKeyIdentifier = hash nameConstraints = critical")?; for v in subcerts { - write!(&mut t3, ", permitted;DNS:{}", v)?; + write!(&mut t3, ", permitted;DNS:{v}")?; } cmd.arg("-extfile"); cmd.arg(t3.path()); @@ -171,8 +170,7 @@ pub async fn generate_ssh_crt( let output_certificate_path = tmp_dir.path().join("thing-cert.pub"); writeln!( ssh_host_ca_key_file, - "-----BEGIN OPENSSH PRIVATE KEY-----\n{}\n-----END OPENSSH PRIVATE KEY-----", - ca_private_key + "-----BEGIN OPENSSH PRIVATE KEY-----\n{ca_private_key}\n-----END OPENSSH PRIVATE KEY-----" )?; ssh_host_ca_key_file.flush()?; @@ -187,7 +185,7 @@ pub async fn generate_ssh_crt( cmd.arg("-n"); cmd.arg(principal); cmd.arg("-V"); - cmd.arg(format!("-5m:+{}d", validity_days)); + cmd.arg(format!("-5m:+{validity_days}d")); cmd.arg("-z"); cmd.arg("42"); cmd.arg(&client_public_key_path); diff --git a/src/bin/server/db.rs b/src/bin/server/db.rs index 54047f3f..ea578227 100644 --- a/src/bin/server/db.rs +++ b/src/bin/server/db.rs @@ -214,7 +214,7 @@ pub async fn setup(db: &SqlitePool) -> Result { 10000, id.and_then(|v| v.id).map(|v| v + 1).unwrap_or_default(), ); - info!("Db inited next_object_id = {}", next_object_id); + info!("Db inited next_object_id = {next_object_id}"); Ok(next_object_id) } @@ -386,7 +386,7 @@ pub async fn get_host_variables( ) -> Result, Cow<'static, str>>>> { let host = get_object_by_id_and_type::(state, id, HOST_ID) .await - .with_context(|| format!("Getting host {}", id))?; + .with_context(|| format!("Getting host {id}"))?; let Some(host) = host else { return Ok(None) }; let mut variables = get_root_variables(state).await?; variables.insert("nodename".into(), host.name.into()); @@ -398,7 +398,7 @@ pub async fn get_host_variables( } let Some(o) = get_newest_object_by_id::(state, id) .await - .with_context(|| format!("Getting object {}", id))? + .with_context(|| format!("Getting object {id}"))? else { continue; }; diff --git a/src/bin/server/deployment.rs b/src/bin/server/deployment.rs index c15d8efc..86d52dcb 100644 --- a/src/bin/server/deployment.rs +++ b/src/bin/server/deployment.rs @@ -305,13 +305,9 @@ impl<'a, M> Visitor<'a, M> { Ok(v) => v, Err(e) => { self.errors.push(format!( - "Template error in {} of {}: {:?}", - name, deployment_title, e + "Template error in {name} of {deployment_title}: {e:?}" )); - error!( - "Template error in {} of {}: {:?}", - name, deployment_title, e - ); + error!("Template error in {name} of {deployment_title}: {e:?}"); "".into() } } @@ -502,8 +498,7 @@ impl<'a, M> Visitor<'a, M> { } Err(e) => { self.errors.push(format!( - "Error processing triger of type {} with content {:?}: {:?}", - id, values, e + "Error processing triger of type {id} with content {values:?}: {e:?}" )); } } @@ -530,7 +525,7 @@ impl<'a, M> Visitor<'a, M> { access.rw(sentinal).base_mut().prev.push(s); } Err(e) => { - self.errors.push(format!("{:?}", e)); + self.errors.push(format!("{e:?}")); } } } @@ -568,9 +563,9 @@ impl<'a, M> Visitor<'a, M> { write!(&mut nw, ".")?; } for v in prefix.iter() { - write!(&mut nw, "{}.", v).context("num_len failed 1")?; + write!(&mut nw, "{v}.").context("num_len failed 1")?; } - write!(&mut nw, "{}", id).context("num_len faile 2")?; + write!(&mut nw, "{id}").context("num_len faile 2")?; let name = std::str::from_utf8(name).context("num_len failed 3")?; if let Some(v) = self.nodes.get(name) { @@ -591,7 +586,7 @@ impl<'a, M> Visitor<'a, M> { let type_content = self .types .get(&type_id) - .with_context(|| format!("Missing type {} for object {}", type_id, id))?; + .with_context(|| format!("Missing type {type_id} for object {id}"))?; let type_obj = self.objects.get(&type_id).context("Missing type")?; if path.contains(&id) { bail!( @@ -651,7 +646,7 @@ impl<'a, M> Visitor<'a, M> { if !nv.is_empty() { if let Err(e) = vars.add_str(nv.as_str(), &obj.name) { self.errors - .push(format!("Failed to add varible {}: {:?}", nv, e)); + .push(format!("Failed to add varible {nv}: {e:?}")); } } } @@ -755,7 +750,7 @@ impl<'a, M> Visitor<'a, M> { let c = match self.visit(access, id, &mut path, &mut prefix, &mut vars) { Ok(v) => Some(v), Err(e) => { - self.errors.push(format!("Error visiting {}: {:?}", id, e)); + self.errors.push(format!("Error visiting {id}: {e:?}")); None } }; @@ -818,7 +813,7 @@ async fn setup_deployment_host<'a, M>( let objects = visitor.objects; let host_object = objects .get(&host_id) - .with_context(|| format!("Missing host {}", host_id))?; + .with_context(|| format!("Missing host {host_id}"))?; outer_vars.add_str("nodename", &host_object.name)?; let mut to_visit = vec![host_id]; @@ -1083,10 +1078,10 @@ async fn setup_deployment_host<'a, M>( write!(&mut error, " -> ")?; } match access.ro(n) { - DagNode::Sentinal { name, .. } => write!(&mut error, "Sent {}", name)?, + DagNode::Sentinal { name, .. } => write!(&mut error, "Sent {name}")?, DagNode::Normal { deployment_title, .. - } => write!(&mut error, "{}", deployment_title)?, + } => write!(&mut error, "{deployment_title}")?, } } visitor.errors.push(String::from_utf8(error)?) @@ -1424,11 +1419,11 @@ pub async fn setup_deployment( Err(e) => { mut_deployment(state, |deployment| { deployment.set_status(DeploymentStatus::InvilidTree); - deployment.set_message(format!("{:?}", e)); + deployment.set_message(format!("{e:?}")); Ok(()) }) .await?; - error!("Error in setup deployment: {:?}", e); + error!("Error in setup deployment: {e:?}"); return Ok(()); } }; @@ -1454,11 +1449,11 @@ pub async fn setup_deployment( { mut_deployment(state, |deployment| { deployment.set_status(DeploymentStatus::InvilidTree); - deployment.set_message(format!("{:?}", e)); + deployment.set_message(format!("{e:?}")); Ok(()) }) .await?; - error!("Error in setup deployment: {:?}", e); + error!("Error in setup deployment: {e:?}"); } Ok(()) } @@ -1619,7 +1614,7 @@ async fn perform_deploy(rt: &RunToken, state: &State, mark_only: bool) -> Result for (i2, _) in &sum_objects { deployment.set_object_status(*i2, DeploymentObjectStatus::Failure); } - deployment.add_log(format!("{:?}", e)); + deployment.add_log(format!("{e:?}")); Ok(()) }) .await?; @@ -1634,7 +1629,7 @@ async fn perform_deploy(rt: &RunToken, state: &State, mark_only: bool) -> Result }) .await?; for (_, o2) in sum_objects { - info!("DEBUG SET DEPLOYMENT {:?} type_id={}", o2, type_id); + info!("DEBUG SET DEPLOYMENT {o2:?} type_id={type_id}"); set_deployment(state, o2, type_id).await?; } } @@ -1673,7 +1668,7 @@ async fn perform_deploy(rt: &RunToken, state: &State, mark_only: bool) -> Result if let Err(e) = ret { rt.set_location(file!(), line!()); mut_deployment(state, move |deployment| { - deployment.add_log(format!("{:?}", e)); + deployment.add_log(format!("{e:?}")); Ok(()) }) .await?; diff --git a/src/bin/server/docker.rs b/src/bin/server/docker.rs index 3ded68f8..51c32e33 100644 --- a/src/bin/server/docker.rs +++ b/src/bin/server/docker.rs @@ -153,7 +153,7 @@ async fn prune_inner(state: &State) -> Result<()> { let path = std::path::Path::new(DOCKER_BLOBS_PATH).join(p); async move { if let Err(e) = tokio::fs::remove_file(&path).await { - warn!("Unable to remove {:?}: {:?}", path, e); + warn!("Unable to remove {path:?}: {e:?}"); } } }) @@ -177,7 +177,7 @@ pub async fn docker_prune(state: Arc, run_token: RunToken) -> Result<()> // TODO(jakobt) make prune_inner cancable // prune docker images every 12 houers if let Err(e) = prune_inner(&state).await { - error!("Error pruning docker blobs: {:?}", e); + error!("Error pruning docker blobs: {e:?}"); } } Ok(()) @@ -286,7 +286,7 @@ async fn deploy_server_inner2( project: Option, do_template: bool, ) -> Result<(), anyhow::Error> { - info!("service deploy start ref: {:?}", r#ref); + info!("service deploy start ref: {ref:?}"); let auth = client.get_auth(); let user = auth.user.context("Missing user")?; let mut variables = db::get_host_variables(state, host_id) @@ -297,7 +297,7 @@ async fn deploy_server_inner2( let mut buf = [0; 24]; crypt::random_fill(&mut buf)?; variables.insert( - format!("token_{}", i).into(), + format!("token_{i}").into(), BASE64_STANDARD.encode(buf).into(), ); } @@ -309,17 +309,15 @@ async fn deploy_server_inner2( let description_str = crate::mustache::render(&description_template, None, &variables, true) .context("Unable to render description template 1")?; - let description: ServiceDescription = - serde_yaml::from_str(&description_str).with_context(|| { - format!("Deserializing service description 1 '{}'", description_str) - })?; + let description: ServiceDescription = serde_yaml::from_str(&description_str) + .with_context(|| format!("Deserializing service description 1 '{description_str}'"))?; if let (Some(ssl_service), Some(ssl_identity)) = (description.ssl_service, description.ssl_identity) { let ca_key = &state.docker.ca_key; let ca_crt = &state.docker.ca_crt; let my_key = crt::generate_key().await.context("generate_key")?; - let my_srs = crt::generate_srs(&my_key, &format!("{}.{}", ssl_identity, ssl_service)) + let my_srs = crt::generate_srs(&my_key, &format!("{ssl_identity}.{ssl_service}")) .await .context("generate_srs")?; @@ -336,14 +334,8 @@ async fn deploy_server_inner2( variables.insert("ssl_pem".into(), crt::strip(&my_crt).to_string().into()); extra_env.insert("CA_PEM".to_string(), crt::strip(ca_crt).to_string()); let service_uc = ssl_service.to_uppercase(); - extra_env.insert( - format!("{}_KEY", service_uc), - crt::strip(&my_key).to_string(), - ); - extra_env.insert( - format!("{}_PEM", service_uc), - crt::strip(&my_crt).to_string(), - ); + extra_env.insert(format!("{service_uc}_KEY"), crt::strip(&my_key).to_string()); + extra_env.insert(format!("{service_uc}_PEM"), crt::strip(&my_crt).to_string()); } else { variables.remove("ca_pem"); variables.remove("ssl_key"); @@ -357,7 +349,7 @@ async fn deploy_server_inner2( description_template.into() }; let description: ServiceDescription = serde_yaml::from_str(&description_str) - .with_context(|| format!("Deserializing service description 2 '{}'", description_str))?; + .with_context(|| format!("Deserializing service description 2 '{description_str}'"))?; let name = description.name; let (project, hash, image) = if let Some(project) = project { (project, hash, image) @@ -390,7 +382,7 @@ async fn deploy_server_inner2( (image, hash) }; let hash = hash.context("Could not find image to deploy")?; - let image = format!("{}@{}", project, hash); + let image = format!("{project}@{hash}"); if let Some(p) = &description.project { if p != project { @@ -491,7 +483,7 @@ async fn deploy_server_inner3( description: description_str.to_string(), extra_env, image, - docker_auth: Some(BASE64_STANDARD.encode(format!("docker_client:{}", session))), + docker_auth: Some(BASE64_STANDARD.encode(format!("docker_client:{session}"))), user: Some(user.clone()), })) .await?; @@ -657,14 +649,14 @@ pub async fn redploy_service( let rt = RunToken::new(); let r#ref = act.r#ref.clone(); if let Err(e) = redploy_service_inner(state, client, act).await { - error!("Service redeployment failed: {:?}", e); + error!("Service redeployment failed: {e:?}"); client .send_message( &rt, IServerAction::DockerDeployEnd(IDockerDeployEnd { r#ref, status: false, - message: format!("Deployment failed {}", e), + message: format!("Deployment failed {e}"), id: None, }), ) @@ -704,14 +696,14 @@ pub async fn deploy_service( .await { let rt = RunToken::new(); - error!("Service deployment failed: {:?}", e); + error!("Service deployment failed: {e:?}"); client .send_message( &rt, IServerAction::DockerDeployEnd(IDockerDeployEnd { r#ref: act.r#ref, status: false, - message: format!("Deployment failed {}", e), + message: format!("Deployment failed {e}"), id: None, }), ) diff --git a/src/bin/server/docker_web.rs b/src/bin/server/docker_web.rs index d67b1373..82b7148b 100644 --- a/src/bin/server/docker_web.rs +++ b/src/bin/server/docker_web.rs @@ -150,14 +150,14 @@ macro_rules! api_error { pub async fn init_upload() -> Result<(), anyhow::Error> { tokio::fs::remove_dir_all(DOCKER_UPLOAD_PATH) .await - .with_context(|| format!("Failure removing {}", DOCKER_UPLOAD_PATH))?; + .with_context(|| format!("Failure removing {DOCKER_UPLOAD_PATH}"))?; tokio::fs::create_dir(DOCKER_UPLOAD_PATH) .await - .with_context(|| format!("Failure creating {}", DOCKER_UPLOAD_PATH))?; + .with_context(|| format!("Failure creating {DOCKER_UPLOAD_PATH}"))?; match tokio::fs::create_dir(DOCKER_BLOBS_PATH).await { Ok(()) => (), Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (), - Err(e) => return Err(e).context(format!("Failure creating {}", DOCKER_BLOBS_PATH)), + Err(e) => return Err(e).context(format!("Failure creating {DOCKER_BLOBS_PATH}")), } Ok(()) } @@ -608,10 +608,7 @@ async fn put_blob_upload( ); } - info!( - "Docker put blob uuid={} total_size={} digest={}", - uuid, count, actual_digest - ); + info!("Docker put blob uuid={uuid} total_size={count} digest={actual_digest}"); tokio::fs::rename( std::path::Path::new(DOCKER_UPLOAD_PATH).join(uuid.to_string()), std::path::Path::new(DOCKER_BLOBS_PATH).join(&actual_digest), @@ -623,7 +620,7 @@ async fn put_blob_upload( StatusCode::CREATED, [ ("ContentLength", "0".to_string()), - ("Location", format!("/v2/{}/blobs/{}", name, actual_digest)), + ("Location", format!("/v2/{name}/blobs/{actual_digest}")), ("Docker-Content-Digest", actual_digest), ], "Created", @@ -641,7 +638,7 @@ async fn put_manifest( if state.read_only { api_error!(SERVICE_UNAVAILABLE, Unsupported, "Service read only",); } - info!("Docker put manifest name={} tag={}", name, reference); + info!("Docker put manifest name={name} tag={reference}"); // Validate that manifest is JSON. let manifest: crate::docker::Manifest = match serde_json::from_str(&body) { @@ -804,7 +801,7 @@ async fn put_manifest( StatusCode::CREATED, [ ("ContentLength", "0".to_string()), - ("Location", format!("/v2/{}/manifests/{}", name, hash)), + ("Location", format!("/v2/{name}/manifests/{hash}")), ("Docker-Content-Digest", hash), ], (), @@ -900,7 +897,7 @@ async fn patch_blob_upload( Ok(( StatusCode::ACCEPTED, [ - ("Location", format!("/v2/{}/blobs/uploads/{}", name, uuid)), + ("Location", format!("/v2/{name}/blobs/uploads/{uuid}")), ("Range", format!("0-{}", inner.count - 1)), ("Content-Length", "0".to_string()), ("Docker-Upload-UUID", uuid.to_string()), @@ -925,7 +922,7 @@ async fn post_blob_upload( let path = std::path::Path::new(DOCKER_UPLOAD_PATH).join(uuid.to_string()); let file = tokio::fs::File::create_new(&path) .await - .with_context(|| format!("Unable to create file {:?}", path)) + .with_context(|| format!("Unable to create file {path:?}")) .to_api_error("File creation failed")?; // TODO(jakobt) we should add some timeout here to not have the file there forever @@ -946,7 +943,7 @@ async fn post_blob_upload( StatusCode::ACCEPTED, [ ("Content-Length", "0".to_string()), - ("Location", format!("/v2/{}/blobs/uploads/{}", name, uuid)), + ("Location", format!("/v2/{name}/blobs/uploads/{uuid}")), ("Range", "0-0".to_string()), ("Docker-Upload-UUID", uuid.to_string()), ], diff --git a/src/bin/server/hostclient.rs b/src/bin/server/hostclient.rs index 0b026d2b..1830466e 100644 --- a/src/bin/server/hostclient.rs +++ b/src/bin/server/hostclient.rs @@ -260,7 +260,7 @@ impl HostClient { async fn send_ping(self: Arc, _rt: RunToken, id: u64) -> Result<()> { if let Err(e) = self.send_message(&HostClientMessage::Ping { id }).await { - error!("Failed sending ping: {:?}", e) + error!("Failed sending ping: {e:?}") } Ok(()) } @@ -308,40 +308,40 @@ impl HostClient { } ClientHostMessage::SocketRecv{ socket_id, data } => { match self.socket_message_handlers.lock().unwrap().get(&socket_id) { - None => warn!("Get recv for unknows socket {}", socket_id), + None => warn!("Get recv for unknows socket {socket_id}"), Some(v) => { if let Err(e) = v.send(ClientHostMessage::SocketRecv{ socket_id, data }) { - warn!("Failed forwarding recv message for socket {}: {:?}", socket_id, e); + warn!("Failed forwarding recv message for socket {socket_id}: {e:?}"); } } } } ClientHostMessage::CommandStdout{ command_id, data } => { match self.command_message_handlers.lock().unwrap().get(&command_id) { - None => warn!("Get stdout for unknown command {}", command_id), + None => warn!("Get stdout for unknown command {command_id}"), Some(v) => { if let Err(e) = v.send(ClientHostMessage::CommandStdout{ command_id, data }) { - warn!("Failed forwarding stdout message to command {}: {:?}", command_id, e); + warn!("Failed forwarding stdout message to command {command_id}: {e:?}"); } } } } ClientHostMessage::CommandStderr{ command_id, data } => { match self.command_message_handlers.lock().unwrap().get(&command_id) { - None => warn!("Get stderr for unknown command {}", command_id), + None => warn!("Get stderr for unknown command {command_id}"), Some(v) => { if let Err(e) = v.send(ClientHostMessage::CommandStderr{ command_id, data }) { - warn!("Failed forwarding stderr message to command {}: {:?}", command_id, e); + warn!("Failed forwarding stderr message to command {command_id}: {e:?}"); } } } } ClientHostMessage::CommandFinished{ command_id, code, signal } => { match self.command_message_handlers.lock().unwrap().get(&command_id) { - None => warn!("Get finished for unknown command {}", command_id), + None => warn!("Get finished for unknown command {command_id}"), Some(v) => { if let Err(e) = v.send(ClientHostMessage::CommandFinished{ command_id, code, signal }) { - warn!("Failed forwarding finished message to command {}: {:?}", command_id, e); + warn!("Failed forwarding finished message to command {command_id}: {e:?}"); } } } @@ -350,11 +350,11 @@ impl HostClient { if let Some(id) = msg.job_id() { if let Some(job) = self.job_sinks.lock().unwrap().get(&id) { if let Err(e) = job.send(msg) { - error!("Unable to handle job message: {:?}", e); + error!("Unable to handle job message: {e:?}"); } } else if let Some(s) = self.message_handlers.lock().unwrap().remove(&id) { if let Err(e) = s.send(msg) { - error!("Unable to handle job message: {:?}", e); + error!("Unable to handle job message: {e:?}"); } } else if self.clone().spawn_kill_job(id) { error!("Got message from unknown job {} on host {}", id, self.hostname); @@ -572,7 +572,7 @@ async fn handle_host_client( ) .await???; - info!("Host connected {:?}", peer_address); + info!("Host connected {peer_address:?}"); let (mut reader, writer) = tokio::io::split(stream); let mut buf = BytesMut::with_capacity(1024 * 128); let (id, hostname) = match cancelable( @@ -586,12 +586,12 @@ async fn handle_host_client( { Ok(Ok(Ok(id))) => id, Ok(Ok(Err(e))) => { - warn!("Host auth error for {:?}: {:?}", peer_address, e); + warn!("Host auth error for {peer_address:?}: {e:?}"); reader.unsplit(writer); return Ok(()); } Ok(Err(_)) => { - warn!("Host auth timeout for {:?}", peer_address); + warn!("Host auth timeout for {peer_address:?}"); reader.unsplit(writer); return Ok(()); } @@ -600,7 +600,7 @@ async fn handle_host_client( return Ok(()); } }; - info!("Host authorized {:?} {} ({})", peer_address, hostname, id); + info!("Host authorized {peer_address:?} {hostname} ({id})"); let j: u32 = rand::rng().random(); @@ -695,7 +695,7 @@ pub async fn run_host_server(state: Arc, run_token: RunToken) -> Result<( tokio::select! { accept_res = accept_fut => { let (stream, peer_address) = accept_res?; - TaskBuilder::new(format!("host_client_{:?}", peer_address)) + TaskBuilder::new(format!("host_client_{peer_address:?}")) .shutdown_order(2) .create(|rt|handle_host_client(state.clone(), rt, stream, peer_address, acceptor.clone())); } diff --git a/src/bin/server/modified_files.rs b/src/bin/server/modified_files.rs index 0b2085e5..6baaecbb 100644 --- a/src/bin/server/modified_files.rs +++ b/src/bin/server/modified_files.rs @@ -182,7 +182,7 @@ pub async fn scan_inner(state: &State) -> Result<()> { let Some(c) = content.content else { continue }; ( c.unit, - c.name.map(|v| format!("/etc/systemd/system/{}.service", v)), + c.name.map(|v| format!("/etc/systemd/system/{v}.service")), content.object, ) } @@ -212,7 +212,7 @@ pub async fn scan_inner(state: &State) -> Result<()> { for (host_id, objs) in &objects { let paths: Vec<_> = objs.iter().map(|v| v.path.clone()).collect(); let Some(host) = state.host_clients.lock().unwrap().get(host_id).cloned() else { - warn!("Host {} not up", host_id); + warn!("Host {host_id} not up"); continue; }; futures.push(run_host_scan_job(*host_id, host, paths)); @@ -227,11 +227,11 @@ pub async fn scan_inner(state: &State) -> Result<()> { Ok(v) => v, Err(e) => { return Err(e) - .with_context(|| format!("Failed getting host content on {}", host)); + .with_context(|| format!("Failed getting host content on {host}")); } }; let content: Vec = serde_json::from_str(&content) - .with_context(|| format!("Failed reading host content:\n {}", content))?; + .with_context(|| format!("Failed reading host content:\n {content}"))?; let objs = objects .remove(&host) .context("Got content from unknown host")?; @@ -273,7 +273,7 @@ pub async fn scan_inner(state: &State) -> Result<()> { for (path, (deployed, r#type, object, actual)) in modified.into_iter() { messages.push(( host, - format!("The file {} has been modified since it was deployed", path), + format!("The file {path} has been modified since it was deployed"), )); let id = inner.idc; inner.idc += 1; @@ -398,7 +398,7 @@ with open({}, 'w', encoding='utf-8') as f: bail!("Failure in resolve job") } Some(ClientHostMessage::Data(m)) => { - info!("Unexpected data in resolve {:?}", m); + info!("Unexpected data in resolve {m:?}"); } Some(msg) => { bail!("Got unknown message {} in resolve", msg.tag()); @@ -590,7 +590,7 @@ pub async fn modified_files_scan(state: Arc, run_token: RunToken) -> Resu match cancelable(&run_token, scan(&state)).await { Ok(Ok(())) => (), Ok(Err(e)) => { - error!("Error in modified_files.scan {:?}", e); + error!("Error in modified_files.scan {e:?}"); } Err(_) => break, } diff --git a/src/bin/server/vanta.rs b/src/bin/server/vanta.rs index c3df9dc3..dfa721b5 100644 --- a/src/bin/server/vanta.rs +++ b/src/bin/server/vanta.rs @@ -97,7 +97,7 @@ async fn push_users(config: &Config, db: &SqlitePool) -> Result<()> { continue; }; if !email.contains("@") { - error!("Invalid email '{}'", email); + error!("Invalid email '{email}'"); continue; } resources.push(VantaUser { @@ -129,8 +129,8 @@ async fn push_users(config: &Config, db: &SqlitePool) -> Result<()> { let r = client .post("https://api.vanta.com/oauth/token") .json(&VantaTokenRequest { - client_id: client_id, - client_secret: client_secret, + client_id, + client_secret, scope: "connectors.self:write-resource", grant_type: "client_credentials", }) @@ -144,7 +144,7 @@ async fn push_users(config: &Config, db: &SqlitePool) -> Result<()> { if let Err(e) = r.error_for_status_ref() { let text = r.text().await?; - return Err(e).context(format!("Faild executing token request: {}", text)); + return Err(e).context(format!("Faild executing token request: {text}")); } let token: VantaTokenResponse = r.json().await.context("Failed getting token")?; @@ -167,7 +167,7 @@ async fn push_users(config: &Config, db: &SqlitePool) -> Result<()> { if let Err(e) = r.error_for_status_ref() { let text = r.text().await?; - return Err(e).context(format!("Failed executing users request: {}", text)); + return Err(e).context(format!("Failed executing users request: {text}")); } let response: VantaSyncResponse = r @@ -236,8 +236,8 @@ async fn analyze_host(state: &State, id: i64) -> Result return Err(HostStatus::Timeout), - Ok(Err(_)) => return Err(HostStatus::HostDown), + Err(_) => Err(HostStatus::Timeout), + Ok(Err(_)) => Err(HostStatus::HostDown), Ok(Ok(Some(ClientHostMessage::Success(msg)))) => { if let Some(code) = msg.code { if code != 0 { @@ -250,11 +250,11 @@ async fn analyze_host(state: &State, id: i64) -> Result(data) else { return Err(HostStatus::InvalidJson); }; - return Ok(result); + Ok(result) } - Ok(Ok(Some(ClientHostMessage::Failure(_)))) => return Err(HostStatus::CommandFailed), - Ok(Ok(Some(_))) => return Err(HostStatus::WrongMessage), - Ok(Ok(None)) => return Err(HostStatus::HostDown), + Ok(Ok(Some(ClientHostMessage::Failure(_)))) => Err(HostStatus::CommandFailed), + Ok(Ok(Some(_))) => Err(HostStatus::WrongMessage), + Ok(Ok(None)) => Err(HostStatus::HostDown), } } @@ -349,7 +349,7 @@ pub async fn push_hosts(state: &State) -> Result<()> { custom_properties: VantaHostResourceCustom { category: row.category, firewall: false, - status: status, + status, ufw_status: None, distribution: None, uname: None, @@ -365,8 +365,8 @@ pub async fn push_hosts(state: &State) -> Result<()> { let r = client .post("https://api.vanta.com/oauth/token") .json(&VantaTokenRequest { - client_id: client_id, - client_secret: client_secret, + client_id, + client_secret, scope: "connectors.self:write-resource", grant_type: "client_credentials", }) @@ -380,7 +380,7 @@ pub async fn push_hosts(state: &State) -> Result<()> { if let Err(e) = r.error_for_status_ref() { let text = r.text().await?; - return Err(e).context(format!("Faild executing token request: {}", text)); + return Err(e).context(format!("Faild executing token request: {text}")); } let token: VantaTokenResponse = r.json().await.context("Failed getting token")?; @@ -404,7 +404,7 @@ pub async fn push_hosts(state: &State) -> Result<()> { if let Err(e) = r.error_for_status_ref() { let text = r.text().await?; - return Err(e).context(format!("Failed executing hosts request: {}", text)); + return Err(e).context(format!("Failed executing hosts request: {text}")); } let response: VantaSyncResponse = r @@ -424,11 +424,11 @@ pub async fn push_hosts(state: &State) -> Result<()> { pub async fn run_vanta(state: Arc, run_token: RunToken) -> Result<()> { loop { if let Err(e) = push_users(&state.config, &state.db).await { - error!("Failed sending vanta users: {:?}", e); + error!("Failed sending vanta users: {e:?}"); } if let Err(e) = push_hosts(&state).await { - error!("Failed sending vanta hosts: {:?}", e); + error!("Failed sending vanta hosts: {e:?}"); } if cancelable( diff --git a/src/bin/server/webclient.rs b/src/bin/server/webclient.rs index 157b45a8..e6c98002 100644 --- a/src/bin/server/webclient.rs +++ b/src/bin/server/webclient.rs @@ -80,10 +80,10 @@ pub async fn alert_error( place: &str, webclient: Option<&WebClient>, ) -> Result<()> { - error!("An error occoured in {}: {:?}", place, err); + error!("An error occoured in {place}: {err:?}"); let act = IServerAction::Alert(IAlert { - message: format!("An error occoured in {}: {:?}", place, err), - title: format!("Error in {}", place), + message: format!("An error occoured in {place}: {err:?}"), + title: format!("Error in {place}"), }); if let Some(webclient) = webclient { webclient.send_message(rt, act).await?; @@ -214,7 +214,7 @@ impl WebClient { let ca_key = &state.docker.ca_key; let ca_crt = &state.docker.ca_crt; let key = crt::generate_key().await?; - let srs = crt::generate_srs(&key, &format!("{}.user", sslname)).await?; + let srs = crt::generate_srs(&key, &format!("{sslname}.user")).await?; let crt = crt::generate_crt(ca_key, ca_crt, &srs, &[], auth.auth_days.unwrap_or(1)).await?; let mut res = IGenerateKeyRes { r#ref: act.r#ref, @@ -234,7 +234,7 @@ impl WebClient { ) { res.ssh_crt = Some( crt::generate_ssh_crt( - &format!("{} sadmin user", user), + &format!("{user} sadmin user"), &user, ssh_host_ca_key, &ssh_public_key, @@ -804,7 +804,7 @@ impl WebClient { pub async fn send_response(&self, rt: &RunToken, msg_id: u64, r: Result<()>) -> Result<()> { let error = match r { Ok(_) => None, - Err(e) => Some(format!("{:?}", e)), + Err(e) => Some(format!("{e:?}")), }; self.send_message(rt, IServerAction::Response(IResponse { msg_id, error })) .await?; @@ -901,13 +901,13 @@ os.execv(sys.argv[1], sys.argv[1:]) let status = match r { Ok(code) => code, Err(e) => { - error!("Failure in run command: {:?}", e); + error!("Failure in run command: {e:?}"); self.send_message( rt, IServerAction::RunCommandOutput(IRunCommandOutput { id: act_id, stdout: None, - stderr: Some(BASE64_STANDARD.encode(format!("{:?}", e))), + stderr: Some(BASE64_STANDARD.encode(format!("{e:?}"))), }), ) .await?; @@ -1025,7 +1025,7 @@ os.execv(sys.argv[1], sys.argv[1:]) IClientAction::Login(act) => { rt.set_location(file!(), line!()); if let Err(e) = self.handle_login_inner(&rt, state, act).await { - error!("Error in handle_login: {:?}", e); + error!("Error in handle_login: {e:?}"); rt.set_location(file!(), line!()); self.send_message( &rt, @@ -1102,7 +1102,7 @@ os.execv(sys.argv[1], sys.argv[1:]) let id = match self.get_object_id_inner(state, &act).await { Ok(v) => Some(v), Err(e) => { - error!("Failure in getObjectId {:?}", e); + error!("Failure in getObjectId {e:?}"); None } }; @@ -1463,7 +1463,7 @@ os.execv(sys.argv[1], sys.argv[1:]) .await { Ok(v) => v, Err(e) => { - error!("ERROR IN QUERY {:?}", e); + error!("ERROR IN QUERY {e:?}"); return Err(e.into()) } }; @@ -2106,7 +2106,7 @@ async fn sysadmin_handler( ) -> Response { ws.on_upgrade(move |socket| async move { if let Err(e) = handle_webclient(socket, state, remote).await { - error!("Error in websocket connection: {:?}", e); + error!("Error in websocket connection: {e:?}"); } }) } @@ -2144,7 +2144,7 @@ async fn metrics_handler(WState(state): WState>) -> Result serde::Deserialize<'de> for IPage { 10 => IPage::Object(Deserialize::deserialize(value).map_err(D::Error::custom)?), 11 => IPage::ObjectList(Deserialize::deserialize(value).map_err(D::Error::custom)?), 12 => IPage::Search, - type_ => return Err(D::Error::custom(format!("Unsupported type {}", type_))), + type_ => return Err(D::Error::custom(format!("Unsupported type {type_}"))), }, ) } diff --git a/src/type_types.rs b/src/type_types.rs index 68e2b414..4936d06a 100644 --- a/src/type_types.rs +++ b/src/type_types.rs @@ -241,7 +241,7 @@ impl<'de> serde::Deserialize<'de> for ITypeProp { INumberTypeProp::deserialize(value).map_err(D::Error::custom)?, ), 8 => ITypeProp::Monitor, - type_ => return Err(D::Error::custom(format!("Unsupported type {}", type_))), + type_ => return Err(D::Error::custom(format!("Unsupported type {type_}"))), }, ) } From 6304175e0afa11a0e94482cbc5f9ea5ea071e2bf Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Wed, 2 Jul 2025 10:09:30 +0200 Subject: [PATCH 5/6] run: Forward more signals --- src/bin/sadmin/run.rs | 103 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/src/bin/sadmin/run.rs b/src/bin/sadmin/run.rs index ee4bb7d5..1535d89b 100644 --- a/src/bin/sadmin/run.rs +++ b/src/bin/sadmin/run.rs @@ -279,22 +279,86 @@ pub async fn run(config: Config, args: Run) -> Result<()> { }; pin!(process_stdin); - let send2 = send.clone(); - let mut do_process_ctrl_c: bool = true; - let process_ctrl_c = async move { - signal::ctrl_c().await.context("Reading ctrl+c")?; - let msg_id = next_msg_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - send2 - .send_message_with_response(&IClientAction::CommandSignal(ICommandSignal { + #[cfg(not(feature = "nix"))] + struct Forever; + #[cfg(not(feature = "nix"))] + impl Future for Forever { + type Output = Result; + fn poll( + self: std::pin::Pin<&mut Self>, + _: &mut std::task::Context<'_>, + ) -> std::task::Poll { + std::task::Poll::Pending + } + } + #[cfg(not(feature = "nix"))] + let forward_sighub = Forever; + #[cfg(not(feature = "nix"))] + let forward_sigterm = Forever; + #[cfg(not(feature = "nix"))] + let forward_sigusr1 = Forever; + #[cfg(not(feature = "nix"))] + let forward_sigusr2 = Forever; + + #[cfg(feature = "nix")] + async fn forward_signal( + signal: i32, + send: std::sync::Arc, + command_id: u64, + next_msg_id: &AtomicU64, + ) -> Result<()> { + loop { + signal::unix::signal(tokio::signal::unix::SignalKind::from_raw(signal))? + .recv() + .await; + let msg_id = next_msg_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + send.send_message_with_response(&IClientAction::CommandSignal(ICommandSignal { msg_id, command_id, - signal: 2, + signal, })) .await - .context("Failed sending sigint to remote command")?; + .context("Failed sending signal to remote command")?; + } + } + + #[cfg(feature = "nix")] + let forward_sighub = forward_signal(nix::libc::SIGHUP, send.clone(), command_id, next_msg_id); + + #[cfg(feature = "nix")] + let forward_sigterm = forward_signal(nix::libc::SIGTERM, send.clone(), command_id, next_msg_id); + + #[cfg(feature = "nix")] + let forward_sigusr1 = forward_signal(nix::libc::SIGUSR1, send.clone(), command_id, next_msg_id); + + #[cfg(feature = "nix")] + let forward_sigusr2 = forward_signal(nix::libc::SIGUSR2, send.clone(), command_id, next_msg_id); + + let send2 = send.clone(); + let forward_ctrlc = async move { + loop { + tokio::signal::ctrl_c().await?; + let msg_id = next_msg_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + send2 + .send_message_with_response(&IClientAction::CommandSignal(ICommandSignal { + msg_id, + command_id, + signal: 2, + })) + .await + .context("Failed sending sigint to remote command")?; + } + #[expect(unreachable_code)] Ok::<_, anyhow::Error>(()) }; - pin!(process_ctrl_c); + + pin!( + forward_sighub, + forward_sigterm, + forward_sigusr1, + forward_sigusr2, + forward_ctrlc + ); loop { select! { @@ -320,9 +384,7 @@ pub async fn run(config: Config, args: Run) -> Result<()> { }, ConnectionRecvRes::Message(IServerAction::CommandFinished(a)) => { if let Some(signal) = a.signal { - if signal != 2 || do_process_ctrl_c { - eprintln!("Command finished with signal: {signal}"); - } + eprintln!("Command finished with signal: {signal}"); } std::process::exit(a.code); } @@ -346,9 +408,20 @@ pub async fn run(config: Config, args: Run) -> Result<()> { ConnectionRecvRes::SendPong(v) => send.pong(v).await?, } } - r = &mut process_ctrl_c, if do_process_ctrl_c => { + r = &mut forward_sighub => { + r?; + } + r = &mut forward_sigterm => { + r?; + } + r = &mut forward_sigusr1 => { + r?; + } + r = &mut forward_sigusr2 => { + r?; + } + r = &mut forward_ctrlc => { r?; - do_process_ctrl_c = false; } } } From e97916afa9f0cc551ca889453efe7c7be4975631 Mon Sep 17 00:00:00 2001 From: Jakob Truelsen Date: Wed, 2 Jul 2025 10:14:41 +0200 Subject: [PATCH 6/6] frontend update dependencies --- frontend/biome.jsonc | 62 +- frontend/package-lock.json | 969 ++++++++++++++-------------- frontend/package.json | 36 +- frontend/src/DockerImages.tsx | 4 +- frontend/src/DockerImagesState.ts | 2 +- frontend/src/DockerServices.tsx | 8 +- frontend/src/DockerServicesState.ts | 4 +- frontend/src/HostExtra.tsx | 2 +- frontend/src/MainPage.tsx | 2 +- frontend/src/Menu.tsx | 223 +++---- frontend/src/MenuDropdown.tsx | 7 +- frontend/src/MessageGroup.tsx | 2 +- frontend/src/ModifiedFiles.tsx | 4 +- frontend/src/ModifiedFilesState.ts | 2 +- frontend/src/ObjectView.tsx | 4 +- frontend/src/PageState.ts | 2 +- frontend/src/Type.tsx | 4 +- frontend/src/UnixTime.tsx | 4 +- frontend/src/deployment/Details.tsx | 6 +- frontend/src/deployment/Items.tsx | 2 +- frontend/src/main.tsx | 2 +- frontend/src/setupSocket.ts | 2 +- frontend/src/setupState.ts | 2 +- frontend/src/state.ts | 2 +- frontend/src/style.css | 8 +- 25 files changed, 687 insertions(+), 678 deletions(-) diff --git a/frontend/biome.jsonc b/frontend/biome.jsonc index e71bd707..5c78b37e 100644 --- a/frontend/biome.jsonc +++ b/frontend/biome.jsonc @@ -1,31 +1,39 @@ { - "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json", - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, + "$schema": "https://biomejs.dev/schemas/2.0.6/schema.json", + "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, "style": { - "noNonNullAssertion": "off" - }, + "noNonNullAssertion": "off", + "noParameterAssign": "error", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "error" + }, "suspicious": { - "noExplicitAny": "off" - }, - } - }, - "formatter": { - "enabled": true, - "formatWithErrors": true, - "indentStyle": "space", - "indentWidth": 4, - "lineWidth": 100 - }, - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true, - "defaultBranch": "master" - } + "noExplicitAny": "off" + } + } + }, + "formatter": { + "enabled": true, + "formatWithErrors": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 100 + }, + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true, + "defaultBranch": "master" + } } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a3543269..410d4568 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,43 +8,43 @@ "name": "simple-admin-frontend", "version": "2.0.0", "dependencies": { - "@codemirror/lang-javascript": "^6.2.3", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-markdown": "^6.3.2", - "@codemirror/lang-python": "^6.2.0", + "@codemirror/lang-javascript": "^6.2.4", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.3", + "@codemirror/lang-python": "^6.2.1", "@codemirror/lang-xml": "^6.1.0", "@codemirror/legacy-modes": "^6.5.1", - "@codemirror/merge": "^6.10.0", + "@codemirror/merge": "^6.10.2", "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.0", - "@fontsource/roboto": "^5.2.5", - "@mui/icons-material": "^7.1.0", - "@mui/material": "^7.1.0", - "@uiw/react-codemirror": "^4.23.12", + "@emotion/styled": "^11.14.1", + "@fontsource/roboto": "5.2.6", + "@mui/icons-material": "^7.2.0", + "@mui/material": "^7.2.0", + "@uiw/react-codemirror": "^4.23.14", "@xterm/addon-fit": "^0.10.0", "@xterm/xterm": "^5.5.0", - "diff": "^7.0.0", + "diff": "^8.0.2", "jquery": "^3.7.1", "js-cookie": "^3.0.5", "mobx": "^6.13.7", "mobx-react": "^9.2.0", "qrcode": "^1.5.4", "react": "^19.1.0", - "react-codemirror-merge": "^4.23.12", + "react-codemirror-merge": "^4.23.14", "react-dom": "^19.1.0", - "react-hotkeys-hook": "^5.0.1" + "react-hotkeys-hook": "^5.1.0" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "2.0.6", "@types/diff": "^7.0.2", "@types/jquery": "^3.5.32", "@types/js-cookie": "^3.0.6", "@types/qrcode": "^1.5.5", - "@types/react": "^19.1.3", - "@types/react-dom": "^19.1.3", - "@vitejs/plugin-react": "^4.4.1", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", "typescript": "^5.8.3", - "vite": "^6.3.5" + "vite": "^7.0.0" } }, "node_modules/@ampproject/remapping": { @@ -76,9 +76,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.1.tgz", - "integrity": "sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.7.tgz", + "integrity": "sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==", "dev": true, "license": "MIT", "engines": { @@ -86,22 +86,22 @@ } }, "node_modules/@babel/core": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", - "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz", + "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helpers": "^7.27.1", - "@babel/parser": "^7.27.1", - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1", + "@babel/generator": "^7.27.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.7", + "@babel/types": "^7.27.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -124,13 +124,13 @@ "license": "MIT" }, "node_modules/@babel/generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", - "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.1", - "@babel/types": "^7.27.1", + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -140,13 +140,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.1.tgz", - "integrity": "sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.1", + "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -170,15 +170,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz", - "integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -226,26 +226,26 @@ } }, "node_modules/@babel/helpers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", - "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.1.tgz", - "integrity": "sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz", + "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "@babel/types": "^7.27.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -287,22 +287,22 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", - "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.1.tgz", - "integrity": "sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.1", + "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" }, "engines": { @@ -310,16 +310,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", - "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz", + "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.1", - "@babel/parser": "^7.27.1", - "@babel/template": "^7.27.1", - "@babel/types": "^7.27.1", + "@babel/generator": "^7.27.5", + "@babel/parser": "^7.27.7", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -328,9 +328,9 @@ } }, "node_modules/@babel/types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", - "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz", + "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -341,11 +341,10 @@ } }, "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.0.6.tgz", + "integrity": "sha512-RRP+9cdh5qwe2t0gORwXaa27oTOiQRQvrFf49x2PA1tnpsyU7FIHX4ZOFMtBC4QNtyWsN7Dqkf5EDbg4X+9iqA==", "dev": true, - "hasInstallScript": true, "license": "MIT OR Apache-2.0", "bin": { "biome": "bin/biome" @@ -358,20 +357,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" + "@biomejs/cli-darwin-arm64": "2.0.6", + "@biomejs/cli-darwin-x64": "2.0.6", + "@biomejs/cli-linux-arm64": "2.0.6", + "@biomejs/cli-linux-arm64-musl": "2.0.6", + "@biomejs/cli-linux-x64": "2.0.6", + "@biomejs/cli-linux-x64-musl": "2.0.6", + "@biomejs/cli-win32-arm64": "2.0.6", + "@biomejs/cli-win32-x64": "2.0.6" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.0.6.tgz", + "integrity": "sha512-AzdiNNjNzsE6LfqWyBvcL29uWoIuZUkndu+wwlXW13EKcBHbbKjNQEZIJKYDc6IL+p7bmWGx3v9ZtcRyIoIz5A==", "cpu": [ "arm64" ], @@ -386,9 +385,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.0.6.tgz", + "integrity": "sha512-wJjjP4E7bO4WJmiQaLnsdXMa516dbtC6542qeRkyJg0MqMXP0fvs4gdsHhZ7p9XWTAmGIjZHFKXdsjBvKGIJJQ==", "cpu": [ "x64" ], @@ -403,9 +402,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.0.6.tgz", + "integrity": "sha512-ZSVf6TYo5rNMUHIW1tww+rs/krol7U5A1Is/yzWyHVZguuB0lBnIodqyFuwCNqG9aJGyk7xIMS8HG0qGUPz0SA==", "cpu": [ "arm64" ], @@ -420,9 +419,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.6.tgz", + "integrity": "sha512-CVPEMlin3bW49sBqLBg2x016Pws7eUXA27XYDFlEtponD0luYjg2zQaMJ2nOqlkKG9fqzzkamdYxHdMDc2gZFw==", "cpu": [ "arm64" ], @@ -437,9 +436,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.0.6.tgz", + "integrity": "sha512-geM1MkHTV1Kh2Cs/Xzot9BOF3WBacihw6bkEmxkz4nSga8B9/hWy5BDiOG3gHDGIBa8WxT0nzsJs2f/hPqQIQw==", "cpu": [ "x64" ], @@ -454,9 +453,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.6.tgz", + "integrity": "sha512-mKHE/e954hR/hSnAcJSjkf4xGqZc/53Kh39HVW1EgO5iFi0JutTN07TSjEMg616julRtfSNJi0KNyxvc30Y4rQ==", "cpu": [ "x64" ], @@ -471,9 +470,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.0.6.tgz", + "integrity": "sha512-290V4oSFoKaprKE1zkYVsDfAdn0An5DowZ+GIABgjoq1ndhvNxkJcpxPsiYtT7slbVe3xmlT0ncdfOsN7KruzA==", "cpu": [ "arm64" ], @@ -488,9 +487,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.0.6.tgz", + "integrity": "sha512-bfM1Bce0d69Ao7pjTjUS+AWSZ02+5UHdiAP85Th8e9yV5xzw6JrHXbL5YWlcEKQ84FIZMdDc7ncuti1wd2sdbw==", "cpu": [ "x64" ], @@ -559,9 +558,9 @@ } }, "node_modules/@codemirror/lang-javascript": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz", - "integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.4.tgz", + "integrity": "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -574,9 +573,9 @@ } }, "node_modules/@codemirror/lang-json": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", - "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -584,9 +583,9 @@ } }, "node_modules/@codemirror/lang-markdown": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.2.tgz", - "integrity": "sha512-c/5MYinGbFxYl4itE9q/rgN/sMTjOr8XL5OWnC+EaRMLfCbVUmmubTJfdgpfcSS2SCaT7b+Q+xi3l6CgoE+BsA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.3.tgz", + "integrity": "sha512-1fn1hQAPWlSSMCvnF810AkhWpNLkJpl66CRfIy3vVl20Sl4NwChkorCHqpMtNbXr1EuMJsrDnhEpjZxKZ2UX3A==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.7.1", @@ -599,9 +598,9 @@ } }, "node_modules/@codemirror/lang-python": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.0.tgz", - "integrity": "sha512-+oLTR88uLib84tvb4XmOBBq/dgrctvPXueP3Wjotu4zmHLM2KW2wfswJ6r1BKlfJNcGgdWX1AgUeGEf3E2H5LA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", + "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.3.2", @@ -626,9 +625,9 @@ } }, "node_modules/@codemirror/language": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", - "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.2.tgz", + "integrity": "sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -660,9 +659,9 @@ } }, "node_modules/@codemirror/merge": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.10.0.tgz", - "integrity": "sha512-Omn0gU6MM5cKQGqgKoIhFjUqCNWH/nukCMLXzu/1jOdtiHsxAu3GdENBf1QYkoIC3FSgkF7X/ClOqYeUATQ4Sw==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.10.2.tgz", + "integrity": "sha512-rmHzVkt5FnCtsi0IgvDIDjh/J4LmbfOboB7FMvVl21IHO0p1QM6jSwjkBjBD3D+c+T79OabEqoduCqvJCBV8Yg==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -673,9 +672,9 @@ } }, "node_modules/@codemirror/search": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", - "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz", + "integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -693,9 +692,9 @@ } }, "node_modules/@codemirror/theme-one-dark": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", - "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz", + "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -705,12 +704,13 @@ } }, "node_modules/@codemirror/view": { - "version": "6.36.7", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.7.tgz", - "integrity": "sha512-kCWGW/chWGPgZqfZ36Um9Iz0X2IVpmCjg1P/qY6B6a2ecXtWRRAigmpJ6YgUQ5lTWXMyyVdfmpzhLZmsZQMbtg==", + "version": "6.38.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.0.tgz", + "integrity": "sha512-yvSchUwHOdupXkd7xJ0ob36jdsSR/I+/C+VbY0ffBiL5NiSTEBDfB1ZGWbbIlDd5xgdUkody+lukAdOxYrOBeg==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.5.0", + "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } @@ -812,9 +812,9 @@ "license": "MIT" }, "node_modules/@emotion/styled": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", - "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", @@ -862,9 +862,9 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", "cpu": [ "ppc64" ], @@ -879,9 +879,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "cpu": [ "arm" ], @@ -896,9 +896,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "cpu": [ "arm64" ], @@ -913,9 +913,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", "cpu": [ "x64" ], @@ -930,9 +930,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", "cpu": [ "arm64" ], @@ -947,9 +947,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", "cpu": [ "x64" ], @@ -964,9 +964,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "cpu": [ "arm64" ], @@ -981,9 +981,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "cpu": [ "x64" ], @@ -998,9 +998,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "cpu": [ "arm" ], @@ -1015,9 +1015,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "cpu": [ "arm64" ], @@ -1032,9 +1032,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "cpu": [ "ia32" ], @@ -1049,9 +1049,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "cpu": [ "loong64" ], @@ -1066,9 +1066,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "cpu": [ "mips64el" ], @@ -1083,9 +1083,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "cpu": [ "ppc64" ], @@ -1100,9 +1100,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", "cpu": [ "riscv64" ], @@ -1117,9 +1117,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "cpu": [ "s390x" ], @@ -1134,9 +1134,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", "cpu": [ "x64" ], @@ -1151,9 +1151,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", "cpu": [ "arm64" ], @@ -1168,9 +1168,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", "cpu": [ "x64" ], @@ -1185,9 +1185,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", "cpu": [ "arm64" ], @@ -1202,9 +1202,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", "cpu": [ "x64" ], @@ -1219,9 +1219,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", "cpu": [ "x64" ], @@ -1236,9 +1236,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "cpu": [ "arm64" ], @@ -1253,9 +1253,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "cpu": [ "ia32" ], @@ -1270,9 +1270,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "cpu": [ "x64" ], @@ -1287,26 +1287,22 @@ } }, "node_modules/@fontsource/roboto": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.2.5.tgz", - "integrity": "sha512-70r2UZ0raqLn5W+sPeKhqlf8wGvUXFWlofaDlcbt/S3d06+17gXKr3VNqDODB0I1ASme3dGT5OJj9NABt7OTZQ==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.2.6.tgz", + "integrity": "sha512-hzarG7yAhMoP418smNgfY4fO7UmuUEm5JUtbxCoCcFHT0hOJB+d/qAEyoNjz7YkPU5OjM2LM8rJnW8hfm0JLaA==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1318,25 +1314,16 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1350,14 +1337,14 @@ "license": "MIT" }, "node_modules/@lezer/css": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.11.tgz", - "integrity": "sha512-FuAnusbLBl1SEAtfN8NdShxYJiESKw9LAFysfea1T96jD3ydBn12oYjaSG1a04BQRIUd93/0D8e5CV1cUMkmQg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.2.1.tgz", + "integrity": "sha512-2F5tOqzKEKbCUNraIXc0f6HKeyKlmMWJnBB0i4XW6dJgssrZO/YlZ2pY5xgyqDleqqhiNJ3dQhbrV2aClZQMvg==", "license": "MIT", "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" + "@lezer/lr": "^1.3.0" } }, "node_modules/@lezer/highlight": { @@ -1450,9 +1437,9 @@ "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.1.0.tgz", - "integrity": "sha512-E0OqhZv548Qdc0PwWhLVA2zmjJZSTvaL4ZhoswmI8NJEC1tpW2js6LLP827jrW9MEiXYdz3QS6+hask83w74yQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.2.0.tgz", + "integrity": "sha512-d49s7kEgI5iX40xb2YPazANvo7Bx0BLg/MNRwv+7BVpZUzXj1DaVCKlQTDex3gy/0jsCb4w7AY2uH4t4AJvSog==", "license": "MIT", "funding": { "type": "opencollective", @@ -1460,12 +1447,12 @@ } }, "node_modules/@mui/icons-material": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.1.0.tgz", - "integrity": "sha512-1mUPMAZ+Qk3jfgL5ftRR06ATH/Esi0izHl1z56H+df6cwIlCWG66RXciUqeJCttbOXOQ5y2DCjLZI/4t3Yg3LA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.2.0.tgz", + "integrity": "sha512-gRCspp3pfjHQyTmSOmYw7kUQTd9Udpdan4R8EnZvqPeoAtHnPzkvjBrBqzKaoAbbBp5bGF7BcD18zZJh4nwu0A==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1" + "@babel/runtime": "^7.27.6" }, "engines": { "node": ">=14.0.0" @@ -1475,7 +1462,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^7.1.0", + "@mui/material": "^7.2.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1486,16 +1473,16 @@ } }, "node_modules/@mui/material": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.1.0.tgz", - "integrity": "sha512-ahUJdrhEv+mCp4XHW+tHIEYzZMSRLg8z4AjUOsj44QpD1ZaMxQoVOG2xiHvLFdcsIPbgSRx1bg1eQSheHBgvtg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.2.0.tgz", + "integrity": "sha512-NTuyFNen5Z2QY+I242MDZzXnFIVIR6ERxo7vntFi9K1wCgSwvIl0HcAO2OOydKqqKApE6omRiYhpny1ZhGuH7Q==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/core-downloads-tracker": "^7.1.0", - "@mui/system": "^7.1.0", - "@mui/types": "^7.4.2", - "@mui/utils": "^7.1.0", + "@babel/runtime": "^7.27.6", + "@mui/core-downloads-tracker": "^7.2.0", + "@mui/system": "^7.2.0", + "@mui/types": "^7.4.4", + "@mui/utils": "^7.2.0", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -1514,7 +1501,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^7.1.0", + "@mui/material-pigment-css": "^7.2.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1535,13 +1522,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.1.0.tgz", - "integrity": "sha512-4Kck4jxhqF6YxNwJdSae1WgDfXVg0lIH6JVJ7gtuFfuKcQCgomJxPvUEOySTFRPz1IZzwz5OAcToskRdffElDA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.2.0.tgz", + "integrity": "sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/utils": "^7.1.0", + "@babel/runtime": "^7.27.6", + "@mui/utils": "^7.2.0", "prop-types": "^15.8.1" }, "engines": { @@ -1562,13 +1549,13 @@ } }, "node_modules/@mui/styled-engine": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.1.0.tgz", - "integrity": "sha512-m0mJ0c6iRC+f9hMeRe0W7zZX1wme3oUX0+XTVHjPG7DJz6OdQ6K/ggEOq7ZdwilcpdsDUwwMfOmvO71qDkYd2w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.2.0.tgz", + "integrity": "sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1", - "@emotion/cache": "^11.13.5", + "@babel/runtime": "^7.27.6", + "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", @@ -1596,16 +1583,16 @@ } }, "node_modules/@mui/system": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.1.0.tgz", - "integrity": "sha512-iedAWgRJMCxeMHvkEhsDlbvkK+qKf9me6ofsf7twk/jfT4P1ImVf7Rwb5VubEA0sikrVL+1SkoZM41M4+LNAVA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.2.0.tgz", + "integrity": "sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/private-theming": "^7.1.0", - "@mui/styled-engine": "^7.1.0", - "@mui/types": "^7.4.2", - "@mui/utils": "^7.1.0", + "@babel/runtime": "^7.27.6", + "@mui/private-theming": "^7.2.0", + "@mui/styled-engine": "^7.2.0", + "@mui/types": "^7.4.4", + "@mui/utils": "^7.2.0", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1636,12 +1623,12 @@ } }, "node_modules/@mui/types": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.2.tgz", - "integrity": "sha512-edRc5JcLPsrlNFYyTPxds+d5oUovuUxnnDtpJUbP6WMeV4+6eaX/mqai1ZIWT62lCOe0nlrON0s9HDiv5en5bA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz", + "integrity": "sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1" + "@babel/runtime": "^7.27.6" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1653,14 +1640,14 @@ } }, "node_modules/@mui/utils": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.0.tgz", - "integrity": "sha512-/OM3S8kSHHmWNOP+NH9xEtpYSG10upXeQ0wLZnfDgmgadTAk5F4MQfFLyZ5FCRJENB3eRzltMmaNl6UtDnPovw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/types": "^7.4.2", - "@types/prop-types": "^15.7.14", + "@babel/runtime": "^7.27.6", + "@mui/types": "^7.4.4", + "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.1.0" @@ -1692,10 +1679,17 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", + "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", - "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz", + "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==", "cpu": [ "arm" ], @@ -1707,9 +1701,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", - "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz", + "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==", "cpu": [ "arm64" ], @@ -1721,9 +1715,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", - "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz", + "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==", "cpu": [ "arm64" ], @@ -1735,9 +1729,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", - "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz", + "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==", "cpu": [ "x64" ], @@ -1749,9 +1743,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", - "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz", + "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==", "cpu": [ "arm64" ], @@ -1763,9 +1757,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", - "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz", + "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==", "cpu": [ "x64" ], @@ -1777,9 +1771,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", - "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz", + "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==", "cpu": [ "arm" ], @@ -1791,9 +1785,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", - "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz", + "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==", "cpu": [ "arm" ], @@ -1805,9 +1799,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", - "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz", + "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==", "cpu": [ "arm64" ], @@ -1819,9 +1813,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", - "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz", + "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==", "cpu": [ "arm64" ], @@ -1833,9 +1827,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", - "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz", + "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==", "cpu": [ "loong64" ], @@ -1847,9 +1841,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", - "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz", + "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==", "cpu": [ "ppc64" ], @@ -1861,9 +1855,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", - "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz", + "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==", "cpu": [ "riscv64" ], @@ -1875,9 +1869,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", - "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz", + "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==", "cpu": [ "riscv64" ], @@ -1889,9 +1883,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", - "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz", + "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==", "cpu": [ "s390x" ], @@ -1903,9 +1897,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", - "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz", + "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==", "cpu": [ "x64" ], @@ -1917,9 +1911,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", - "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz", + "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==", "cpu": [ "x64" ], @@ -1931,9 +1925,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", - "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz", + "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==", "cpu": [ "arm64" ], @@ -1945,9 +1939,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", - "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz", + "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==", "cpu": [ "ia32" ], @@ -1959,9 +1953,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", - "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz", + "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==", "cpu": [ "x64" ], @@ -2025,9 +2019,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -2049,13 +2043,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.12.tgz", - "integrity": "sha512-K0fpC/ZVeb8G9rm7bH7vI0KAec4XHEhBam616nVJCV51bKzJ6oA3luG4WdKoaztxe70QaNjS/xBmcDLmr4PiGw==", + "version": "24.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", + "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.8.0" } }, "node_modules/@types/parse-json": { @@ -2065,9 +2059,9 @@ "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.14", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", - "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT" }, "node_modules/@types/qrcode": { @@ -2081,18 +2075,18 @@ } }, "node_modules/@types/react": { - "version": "19.1.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.3.tgz", - "integrity": "sha512-dLWQ+Z0CkIvK1J8+wrDPwGxEYFA4RAyHoZPxHVGspYmFVnwGSNT24cGIhFJrtfRnWVuW8X7NO52gCXmhkVUWGQ==", + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "license": "MIT", "dependencies": { "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "19.1.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.3.tgz", - "integrity": "sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==", + "version": "19.1.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", + "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2116,9 +2110,9 @@ "license": "MIT" }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.23.12", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.12.tgz", - "integrity": "sha512-l9vuiXOTFDBetYrRLDmz3jDxQHDsrVAZ2Y6dVfmrqi2AsulsDu+y7csW0JsvaMqo79rYkaIZg8yeqmDgMb7VyQ==", + "version": "4.23.14", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.14.tgz", + "integrity": "sha512-lCseubZqjN9bFwHJdQlZEKEo2yO1tCiMMVL0gu3ZXwhqMdfnd6ky/fUCYbn8aJkW+cXKVwjEVhpKjOphNiHoNw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -2143,16 +2137,16 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.23.12", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.12.tgz", - "integrity": "sha512-yseqWdzoAAGAW7i/NiU8YrfSLVOEBjQvSx1KpDTFVV/nn0AlAZoDVTIPEBgdXrPlVUQoCrwgpEaj3uZCklk9QA==", + "version": "4.23.14", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.14.tgz", + "integrity": "sha512-/CmlSh8LGUEZCxg/f78MEkEMehKnVklqJvJlL10AXXrO/2xOyPqHb8SK10GhwOqd0kHhHgVYp4+6oK5S+UIEuQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.23.12", + "@uiw/codemirror-extensions-basic-setup": "4.23.14", "codemirror": "^6.0.0" }, "funding": { @@ -2169,15 +2163,16 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz", - "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz", + "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.10", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@babel/core": "^7.27.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.19", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, @@ -2185,7 +2180,7 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, "node_modules/@xterm/addon-fit": { @@ -2243,9 +2238,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", - "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -2263,8 +2258,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001716", - "electron-to-chromium": "^1.5.149", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, @@ -2294,9 +2289,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001717", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz", - "integrity": "sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "dev": true, "funding": [ { @@ -2335,9 +2330,9 @@ } }, "node_modules/codemirror": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", - "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", + "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -2411,9 +2406,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2437,9 +2432,9 @@ } }, "node_modules/diff": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", - "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", + "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -2462,9 +2457,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.150", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.150.tgz", - "integrity": "sha512-rOOkP2ZUMx1yL4fCxXQKDHQ8ZXwisb2OycOQVKHgvB3ZI4CvehOd4y2tfnnLDieJ3Zs1RL1Dlp3cMkyIn7nnXA==", + "version": "1.5.178", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.178.tgz", + "integrity": "sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==", "dev": true, "license": "ISC" }, @@ -2484,9 +2479,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2497,31 +2492,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" } }, "node_modules/escalade": { @@ -2547,9 +2542,9 @@ } }, "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3017,9 +3012,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -3037,7 +3032,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -3089,14 +3084,14 @@ } }, "node_modules/react-codemirror-merge": { - "version": "4.23.12", - "resolved": "https://registry.npmjs.org/react-codemirror-merge/-/react-codemirror-merge-4.23.12.tgz", - "integrity": "sha512-BRacz67tcZ5KQnNodJ9ltMd1WmZyQdREOnxcRfVWUr8USSuIcgn1fVYr+6xaEWFS2tTRJJzjUbemZURrlefIXw==", + "version": "4.23.14", + "resolved": "https://registry.npmjs.org/react-codemirror-merge/-/react-codemirror-merge-4.23.14.tgz", + "integrity": "sha512-CMbDVavtrJr9csJsvqdQ+XEVWgccreklHDEWPoVLgis7bTXrpCZhb6Kq8DtKq1C9fWdkJVpN8ra2NfETX4d8oA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/merge": "^6.1.2", - "@uiw/react-codemirror": "4.23.12" + "@uiw/react-codemirror": "4.23.14" }, "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -3124,9 +3119,9 @@ } }, "node_modules/react-hotkeys-hook": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-5.0.1.tgz", - "integrity": "sha512-TysTwXrUSj6QclMZIEoxCfvy/6EsoZcrfE970aUVa9fO3c3vcms+IVjv3ljbhUPM/oY1iEoun7O2W8v8INl5hw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-5.1.0.tgz", + "integrity": "sha512-GCNGXjBzV9buOS3REoQFmSmE4WTvBhYQ0YrAeeMZI83bhXg3dRWsLHXDutcVDdEjwJqJCxk5iewWYX5LtFUd7g==", "license": "MIT", "workspaces": [ "packages/*" @@ -3213,13 +3208,13 @@ } }, "node_modules/rollup": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", - "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz", + "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -3229,26 +3224,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.40.2", - "@rollup/rollup-android-arm64": "4.40.2", - "@rollup/rollup-darwin-arm64": "4.40.2", - "@rollup/rollup-darwin-x64": "4.40.2", - "@rollup/rollup-freebsd-arm64": "4.40.2", - "@rollup/rollup-freebsd-x64": "4.40.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", - "@rollup/rollup-linux-arm-musleabihf": "4.40.2", - "@rollup/rollup-linux-arm64-gnu": "4.40.2", - "@rollup/rollup-linux-arm64-musl": "4.40.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-musl": "4.40.2", - "@rollup/rollup-linux-s390x-gnu": "4.40.2", - "@rollup/rollup-linux-x64-gnu": "4.40.2", - "@rollup/rollup-linux-x64-musl": "4.40.2", - "@rollup/rollup-win32-arm64-msvc": "4.40.2", - "@rollup/rollup-win32-ia32-msvc": "4.40.2", - "@rollup/rollup-win32-x64-msvc": "4.40.2", + "@rollup/rollup-android-arm-eabi": "4.44.1", + "@rollup/rollup-android-arm64": "4.44.1", + "@rollup/rollup-darwin-arm64": "4.44.1", + "@rollup/rollup-darwin-x64": "4.44.1", + "@rollup/rollup-freebsd-arm64": "4.44.1", + "@rollup/rollup-freebsd-x64": "4.44.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.1", + "@rollup/rollup-linux-arm-musleabihf": "4.44.1", + "@rollup/rollup-linux-arm64-gnu": "4.44.1", + "@rollup/rollup-linux-arm64-musl": "4.44.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1", + "@rollup/rollup-linux-riscv64-gnu": "4.44.1", + "@rollup/rollup-linux-riscv64-musl": "4.44.1", + "@rollup/rollup-linux-s390x-gnu": "4.44.1", + "@rollup/rollup-linux-x64-gnu": "4.44.1", + "@rollup/rollup-linux-x64-musl": "4.44.1", + "@rollup/rollup-win32-arm64-msvc": "4.44.1", + "@rollup/rollup-win32-ia32-msvc": "4.44.1", + "@rollup/rollup-win32-x64-msvc": "4.44.1", "fsevents": "~2.3.2" } }, @@ -3344,9 +3339,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3375,9 +3370,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", "dev": true, "license": "MIT" }, @@ -3422,24 +3417,24 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.0.tgz", + "integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", + "fdir": "^6.4.6", "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -3448,14 +3443,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -3536,9 +3531,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "dev": true, "license": "ISC", "optional": true, @@ -3547,7 +3542,7 @@ "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { diff --git a/frontend/package.json b/frontend/package.json index 695f1920..af18ad71 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,42 +13,42 @@ "format:check": "biome format ./src" }, "dependencies": { - "@codemirror/lang-javascript": "^6.2.3", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-markdown": "^6.3.2", - "@codemirror/lang-python": "^6.2.0", + "@codemirror/lang-javascript": "^6.2.4", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.3", + "@codemirror/lang-python": "^6.2.1", "@codemirror/lang-xml": "^6.1.0", "@codemirror/legacy-modes": "^6.5.1", - "@codemirror/merge": "^6.10.0", + "@codemirror/merge": "^6.10.2", "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.0", - "@fontsource/roboto": "^5.2.5", - "@mui/icons-material": "^7.1.0", - "@mui/material": "^7.1.0", - "@uiw/react-codemirror": "^4.23.12", + "@emotion/styled": "^11.14.1", + "@fontsource/roboto": "5.2.6", + "@mui/icons-material": "^7.2.0", + "@mui/material": "^7.2.0", + "@uiw/react-codemirror": "^4.23.14", "@xterm/addon-fit": "^0.10.0", "@xterm/xterm": "^5.5.0", - "diff": "^7.0.0", + "diff": "^8.0.2", "jquery": "^3.7.1", "js-cookie": "^3.0.5", "mobx": "^6.13.7", "mobx-react": "^9.2.0", "qrcode": "^1.5.4", "react": "^19.1.0", - "react-codemirror-merge": "^4.23.12", + "react-codemirror-merge": "^4.23.14", "react-dom": "^19.1.0", - "react-hotkeys-hook": "^5.0.1" + "react-hotkeys-hook": "^5.1.0" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "2.0.6", "@types/diff": "^7.0.2", "@types/jquery": "^3.5.32", "@types/js-cookie": "^3.0.6", "@types/qrcode": "^1.5.5", - "@types/react": "^19.1.3", - "@types/react-dom": "^19.1.3", - "@vitejs/plugin-react": "^4.4.1", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react": "^4.6.0", "typescript": "^5.8.3", - "vite": "^6.3.5" + "vite": "^7.0.0" } } diff --git a/frontend/src/DockerImages.tsx b/frontend/src/DockerImages.tsx index 277b6015..0e7f6786 100644 --- a/frontend/src/DockerImages.tsx +++ b/frontend/src/DockerImages.tsx @@ -3,12 +3,12 @@ import { observer } from "mobx-react"; import React from "react"; import Box from "./Box"; import DisplayError from "./Error"; -import InfoTable, { InfoTableHeader } from "./InfoTable"; -import UnixTime from "./UnixTime"; import extractRemote from "./extractRemote"; +import InfoTable, { InfoTableHeader } from "./InfoTable"; import nullCheck from "./nullCheck"; import { type IPage, PAGE_TYPE } from "./shared_types"; import state from "./state"; +import UnixTime from "./UnixTime"; export const DockerImages = observer(function DockerImages() { const dockerImages = state.dockerImages; diff --git a/frontend/src/DockerImagesState.ts b/frontend/src/DockerImagesState.ts index 5b75340c..5cf66b86 100644 --- a/frontend/src/DockerImagesState.ts +++ b/frontend/src/DockerImagesState.ts @@ -1,7 +1,7 @@ import { action, makeObservable, observable } from "mobx"; -import type Remote from "./Remote"; import getOrInsert from "./getOrInsert"; import nullCheck from "./nullCheck"; +import type Remote from "./Remote"; import type { DockerImageTag, IDockerListImageTagHistoryRes, diff --git a/frontend/src/DockerServices.tsx b/frontend/src/DockerServices.tsx index 5f877ba0..22265506 100644 --- a/frontend/src/DockerServices.tsx +++ b/frontend/src/DockerServices.tsx @@ -2,12 +2,12 @@ import { Button, Typography } from "@mui/material"; import { observer } from "mobx-react"; import Box from "./Box"; import DisplayError from "./Error"; -import InfoTable, { InfoTableHeader } from "./InfoTable"; -import { InformationList, InformationListRow } from "./InformationList"; -import UnixTime from "./UnixTime"; import extractRemote from "./extractRemote"; +import { InformationList, InformationListRow } from "./InformationList"; +import InfoTable, { InfoTableHeader } from "./InfoTable"; import { HOST_ID, type IPage, PAGE_TYPE } from "./shared_types"; import state from "./state"; +import UnixTime from "./UnixTime"; export const HostDockerContainers = observer(function DockerContainers(p: { host: number; @@ -118,7 +118,7 @@ export const HostDockerContainers = observer(function DockerContainers(p: { ); if (containers.length === 0) { - return <>; + return null; } return ( <> diff --git a/frontend/src/DockerServicesState.ts b/frontend/src/DockerServicesState.ts index ef1669be..4649f5f7 100644 --- a/frontend/src/DockerServicesState.ts +++ b/frontend/src/DockerServicesState.ts @@ -1,6 +1,6 @@ -import { ObservableMap, action, makeObservable, observable } from "mobx"; -import type Remote from "./Remote"; +import { action, makeObservable, ObservableMap, observable } from "mobx"; import getOrInsert from "./getOrInsert"; +import type Remote from "./Remote"; import type { DockerDeployment, IDockerDeploymentsChanged, diff --git a/frontend/src/HostExtra.tsx b/frontend/src/HostExtra.tsx index 38f42f44..313b05a9 100644 --- a/frontend/src/HostExtra.tsx +++ b/frontend/src/HostExtra.tsx @@ -4,8 +4,8 @@ import Box from "./Box"; import { HostDockerContainers } from "./DockerServices"; import Messages from "./Messages"; import Setup from "./Setup"; -import HostTerminals from "./Terminal"; import { state } from "./state"; +import HostTerminals from "./Terminal"; const HostExtra = observer(function HostExtra({ id }: { id: number }) { const [expanded, setExpanded] = useState(false); diff --git a/frontend/src/MainPage.tsx b/frontend/src/MainPage.tsx index 20164830..50ffb6f7 100644 --- a/frontend/src/MainPage.tsx +++ b/frontend/src/MainPage.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react"; import Deployment from "./Deployment"; import { DockerImageHistory, DockerImages } from "./DockerImages"; import { DockerServiceDetails, DockerServiceHistory, DockerServices } from "./DockerServices"; +import DeploymentDetails from "./deployment/Details"; import DisplayError from "./Error"; import Messages from "./Messages"; import { ModifiedFileRevolver, ModifiedFiles } from "./ModifiedFiles"; @@ -10,7 +11,6 @@ import ObjectList from "./ObjectList"; import ObjectView from "./ObjectView"; import Search from "./Search"; import Statuses from "./Statuses"; -import DeploymentDetails from "./deployment/Details"; import { PAGE_TYPE } from "./shared_types"; import state from "./state"; diff --git a/frontend/src/Menu.tsx b/frontend/src/Menu.tsx index 9f4e0cec..f34a4f54 100644 --- a/frontend/src/Menu.tsx +++ b/frontend/src/Menu.tsx @@ -18,13 +18,13 @@ import { import { observer } from "mobx-react"; import { useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; +import derivedState from "./derivedState"; import DisplayError from "./Error"; import MenuDropdown, { DropDownItem } from "./MenuDropdown"; import SubMenu from "./SubMenu"; -import { ObjectMenuList } from "./TypeMenuItems"; -import derivedState from "./derivedState"; import { PAGE_TYPE, ROOT_ID, ROOT_INSTANCE_ID } from "./shared_types"; import state from "./state"; +import { ObjectMenuList } from "./TypeMenuItems"; function matchText(text: string, key: string) { if (!key || key.length === 0) return false; @@ -41,7 +41,11 @@ function MatchedText({ search, text, primary, -}: { search: string; text: string; primary: boolean }) { +}: { + search: string; + text: string; + primary: boolean; +}) { const ans = []; let ki = 0; let j = 0; @@ -102,7 +106,7 @@ const TypeObjects = observer(function TypeObjects({ , ); } - if (ans.length === 0) return <> ; + if (ans.length === 0) return null; const t = state.types.get(type); return ( <> @@ -134,16 +138,14 @@ function Search() { { enabled: key !== "", enableOnContentEditable: true, enableOnFormTags: true }, ); - const page = state.page; - if (!page) return Missing state.page; - const typeFind = []; let goto: [number, number] | null = null; + const page = state.page; useHotkeys( ["return"], () => { - if (goto && searchInput) { + if (goto && searchInput && page) { page.set({ type: PAGE_TYPE.Object, objectType: goto[0], id: goto[1] }); setKey(""); searchInput.blur(); @@ -152,6 +154,8 @@ function Search() { { enabled: key !== "", enableOnContentEditable: true, enableOnFormTags: true }, ); + if (!page) return Missing state.page; + const keyLc = key.toLowerCase(); if (keyLc !== "") { for (const [type, members] of state.objectDigests) { @@ -238,128 +242,127 @@ function Search() { const Menu = observer(function Menu() { const page = state.page; - if (!page) return Missing state.page; const login = state.login; - if (!login) return Missing state.login; const types = derivedState.menuTypes; useHotkeys("d", () => { - page.set({ type: PAGE_TYPE.Dashbord }); + page!.set({ type: PAGE_TYPE.Dashbord }); }); useHotkeys("i", () => { - page.set({ type: PAGE_TYPE.DockerImages }); + page!.set({ type: PAGE_TYPE.DockerImages }); }); useHotkeys("c", () => { - page.set({ type: PAGE_TYPE.DockerServices }); + page!.set({ type: PAGE_TYPE.DockerServices }); }); + if (!page) return Missing state.page; + if (!login) return Missing state.login; + return ( - <> - - {types.map((t) => - t.id === ROOT_ID ? ( - { - page.onClick(e, { - type: PAGE_TYPE.Object, - objectType: ROOT_ID, - id: ROOT_INSTANCE_ID, - }); - }} - href={page.link({ + + {types.map((t) => + t.id === ROOT_ID ? ( + { + page.onClick(e, { type: PAGE_TYPE.Object, objectType: ROOT_ID, id: ROOT_INSTANCE_ID, - })} - > - Root - - ) : ( - - {" "} - {" "} - - ), - )} - - - - - -
- - - + }); + }} + href={page.link({ + type: PAGE_TYPE.Object, + objectType: ROOT_ID, + id: ROOT_INSTANCE_ID, + })} + > + Root + + ) : ( + + {" "} + {" "} + + ), + )} + + -
- -
- - - + + +
+ + + + +
+ +
+ + ); diff --git a/frontend/src/MenuDropdown.tsx b/frontend/src/MenuDropdown.tsx index 44eddb60..f6df1d04 100644 --- a/frontend/src/MenuDropdown.tsx +++ b/frontend/src/MenuDropdown.tsx @@ -37,10 +37,9 @@ function MenuDropdown({ }) { const [open, setOpen] = useState(false); const [anchor, setAnchor] = useState(null); - if (hotkey) - useHotkeys(hotkey, () => { - setOpen(true); - }); + useHotkeys(hotkey ?? "", () => { + setOpen(true); + }); return ( {title ? ( diff --git a/frontend/src/MessageGroup.tsx b/frontend/src/MessageGroup.tsx index b20a6204..a7d67ee1 100644 --- a/frontend/src/MessageGroup.tsx +++ b/frontend/src/MessageGroup.tsx @@ -35,7 +35,7 @@ const MessageGroup = observer(function MessageGroup({ const newDate = new Date(end * 1000); const actions = []; - let c: string | undefined = undefined; + let c: string | undefined; if (dismissed !== 0) { actions.push(