Compare commits
78 Commits
result_nod
...
feat/apped
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30ac3d3679 | ||
|
|
8fcf5de0b8 | ||
|
|
927dbc7b6d | ||
|
|
489d0f7926 | ||
|
|
82c2ac564a | ||
|
|
ce01d975b3 | ||
|
|
74250285fc | ||
|
|
3c50c0ffa3 | ||
|
|
e4583e9b23 | ||
|
|
93063b1c50 | ||
|
|
17d893315b | ||
|
|
0acd1b4a99 | ||
|
|
4b04cc4d1a | ||
|
|
d999e91583 | ||
|
|
9065716020 | ||
|
|
56f70fd7de | ||
|
|
9ad1afc8f2 | ||
|
|
e783f2487a | ||
|
|
c069969732 | ||
|
|
985846f312 | ||
|
|
1a6f89df21 | ||
|
|
9ce1d46459 | ||
|
|
ff5fcc59d4 | ||
|
|
552a0f8ec8 | ||
|
|
5abac8bc2b | ||
|
|
200112cf1f | ||
|
|
4fc09da15d | ||
|
|
2df7c85e2d | ||
|
|
686dc177e8 | ||
|
|
88d75cc584 | ||
|
|
1367296de0 | ||
|
|
51d5987110 | ||
|
|
2fc808c065 | ||
|
|
940af69a6a | ||
|
|
59a9458ca8 | ||
|
|
756b07b16c | ||
|
|
e2ebad90ba | ||
|
|
c724982d33 | ||
|
|
70737c6642 | ||
|
|
b84c76ee9f | ||
|
|
663a193c2a | ||
|
|
70b4bff32c | ||
|
|
42bc803445 | ||
|
|
a1038c32b7 | ||
|
|
8e605a7f0f | ||
|
|
d6dc3be311 | ||
|
|
3207a98d1a | ||
|
|
629e1ec36b | ||
|
|
349be01861 | ||
|
|
d04620e86e | ||
|
|
d4a556d0f6 | ||
|
|
f350e3679b | ||
|
|
e338c28713 | ||
|
|
8549cb20b0 | ||
|
|
4b519a5dc8 | ||
|
|
6b60ccc7ad | ||
|
|
34249143e7 | ||
|
|
14ea9d6b55 | ||
|
|
eaa6e36f9d | ||
|
|
fa9e4ba328 | ||
|
|
322ed7dfd0 | ||
|
|
b91f4372e9 | ||
|
|
67e06d54f0 | ||
|
|
b5f3188239 | ||
|
|
6258c501a2 | ||
|
|
e94c1f9a9d | ||
|
|
d256f41793 | ||
|
|
7d52eecad8 | ||
|
|
d74e406a2d | ||
|
|
d9bd24df95 | ||
|
|
390e46245d | ||
|
|
e1ea5bd2e8 | ||
|
|
546da5b983 | ||
|
|
29c9ba874c | ||
|
|
32f8127e02 | ||
|
|
f875e74064 | ||
|
|
0ae0321e4b | ||
|
|
9aee6f78d0 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## [1.425.1](https://github.com/windmill-labs/windmill/compare/v1.425.0...v1.425.1) (2024-11-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revert bool to text support in pg ([#4727](https://github.com/windmill-labs/windmill/issues/4727)) ([17d8933](https://github.com/windmill-labs/windmill/commit/17d893315bd86942c7895cdb3e9c3ab34977b258))
|
||||
|
||||
## [1.425.0](https://github.com/windmill-labs/windmill/compare/v1.424.0...v1.425.0) (2024-11-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Handle `pip install` by `uv` ([#4517](https://github.com/windmill-labs/windmill/issues/4517)) ([f240d13](https://github.com/windmill-labs/windmill/commit/f240d1322a3c1669dfb69ebda6d05effcca26ae3))
|
||||
* **monitoring:** workspace critical alerts ([#4684](https://github.com/windmill-labs/windmill/issues/4684)) ([c32038a](https://github.com/windmill-labs/windmill/commit/c32038a76d9d00703d8b865af72f083ac43414e3))
|
||||
|
||||
## [1.424.0](https://github.com/windmill-labs/windmill/compare/v1.423.2...v1.424.0) (2024-11-14)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT created_by, CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM queue \n LEFT JOIN job_logs ON job_logs.job_id = queue.id \n WHERE queue.id = $1 AND queue.workspace_id = $2",
|
||||
"query": "SELECT created_by, CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, coalesce(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index\n FROM queue \n LEFT JOIN job_logs ON job_logs.job_id = queue.id \n WHERE queue.id = $1 AND queue.workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -33,9 +33,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "57111a97ff906fd79ecd8a571212cc4fea9cb9c16fe950f082ad5469bfeefc82"
|
||||
"hash": "b2c30137b3b64f8c3f6aea062e8687e119599641beee0a0d6c89c5d90e82d0db"
|
||||
}
|
||||
56
backend/Cargo.lock
generated
56
backend/Cargo.lock
generated
@@ -1032,9 +1032,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
|
||||
checksum = "49c41b948da08fb481a94546cd874843adc1142278b0af4badf9b1b78599d68d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
@@ -4831,9 +4831,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.162"
|
||||
version = "0.2.163"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
checksum = "1fdaeca4cf44ed4ac623e86ef41f056e848dbeab7ec043ecb7326ba300b36fd0"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
@@ -10610,7 +10610,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -10652,7 +10652,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -10737,7 +10737,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -10755,7 +10755,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -10768,7 +10768,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"rsmq_async",
|
||||
@@ -10783,7 +10783,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -10830,7 +10830,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"rsmq_async",
|
||||
@@ -10845,7 +10845,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -10867,7 +10867,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"lazy_static",
|
||||
@@ -10879,7 +10879,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -10888,7 +10888,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10900,7 +10900,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -10912,7 +10912,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10924,7 +10924,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.13.0",
|
||||
@@ -10935,7 +10935,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.13.0",
|
||||
@@ -10946,7 +10946,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -10964,7 +10964,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -10981,7 +10981,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10993,7 +10993,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -11011,7 +11011,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.15",
|
||||
@@ -11032,7 +11032,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -11042,7 +11042,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -11075,7 +11075,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -11085,7 +11085,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -29,7 +29,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.424.0
|
||||
version: 1.425.1
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -950,7 +950,7 @@ async fn get_job_logs(
|
||||
Ok(content_plain(Body::from(logs)))
|
||||
} else {
|
||||
let text = sqlx::query!(
|
||||
"SELECT created_by, CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index
|
||||
"SELECT created_by, CONCAT(coalesce(queue.logs, ''), coalesce(job_logs.logs, '')) as logs, coalesce(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index
|
||||
FROM queue
|
||||
LEFT JOIN job_logs ON job_logs.job_id = queue.id
|
||||
WHERE queue.id = $1 AND queue.workspace_id = $2",
|
||||
@@ -971,10 +971,10 @@ async fn get_job_logs(
|
||||
log_job_view(&db, opt_authed.as_ref(), &w_id, &id).await?;
|
||||
|
||||
#[cfg(all(feature = "enterprise", feature = "parquet"))]
|
||||
if let Some(r) = get_logs_from_store(text.log_offset, &logs, &text.log_file_index).await {
|
||||
if let Some(r) = get_logs_from_store(text.log_offset.unwrap_or(0), &logs, &text.log_file_index).await {
|
||||
return r.map(content_plain);
|
||||
}
|
||||
if let Some(r) = get_logs_from_disk(text.log_offset, &logs, &text.log_file_index).await {
|
||||
if let Some(r) = get_logs_from_disk(text.log_offset.unwrap_or(0), &logs, &text.log_file_index).await {
|
||||
return r.map(content_plain);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ pub const GIT_VERSION: &str =
|
||||
use crate::CRITICAL_ALERT_MUTE_UI_ENABLED;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
#[cfg(feature = "enterprise")]
|
||||
use crate::worker::CLOUD_HOSTED;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@@ -276,7 +275,7 @@ pub async fn report_critical_error(
|
||||
// we ack_global if mute_global is true, or if mute_workspace is true
|
||||
// but we ignore global mute setting for ack_workspace
|
||||
let acknowledge_workspace = mute_workspace;
|
||||
let acknowledge_global = mute_global || mute_workspace;
|
||||
let acknowledge_global = mute_global || mute_workspace || ( workspace_id.is_some() && *CLOUD_HOSTED);
|
||||
|
||||
if let Err(err) = sqlx::query!(
|
||||
"INSERT INTO alerts (alert_type, message, acknowledged, acknowledged_workspace, workspace_id, resource)
|
||||
|
||||
@@ -416,24 +416,32 @@ pub async fn do_postgresql(
|
||||
}
|
||||
|
||||
fn map_as_single_type<T>(
|
||||
vec: &Vec<Value>,
|
||||
vec: Option<&Vec<Value>>,
|
||||
f: impl Fn(&Value) -> Option<T>,
|
||||
) -> anyhow::Result<Vec<Option<T>>> {
|
||||
vec.into_iter()
|
||||
.map(|v| {
|
||||
// allow nulls in arrays
|
||||
if matches!(v, Value::Null) {
|
||||
Some(None)
|
||||
} else {
|
||||
f(v).map(Some)
|
||||
}
|
||||
})
|
||||
.collect::<Option<Vec<Option<T>>>>()
|
||||
.ok_or_else(|| anyhow::anyhow!("Mixed types in array"))
|
||||
) -> anyhow::Result<Option<Vec<Option<T>>>> {
|
||||
if let Some(vec) = vec {
|
||||
Ok(Some(
|
||||
vec.into_iter()
|
||||
.map(|v| {
|
||||
// first option is if the value is of the right type (if none, will stop the collection and throw error)
|
||||
// second option is if the value is null
|
||||
// allow nulls in arrays
|
||||
if matches!(v, Value::Null) {
|
||||
Some(None)
|
||||
} else {
|
||||
f(v).map(Some)
|
||||
}
|
||||
})
|
||||
.collect::<Option<Vec<Option<T>>>>()
|
||||
.ok_or_else(|| anyhow::anyhow!("Mixed types in array"))?,
|
||||
))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_vec_val(
|
||||
vec: &Vec<Value>,
|
||||
vec: Option<&Vec<Value>>,
|
||||
arg_t: &String,
|
||||
) -> windmill_common::error::Result<Box<dyn ToSql + Sync + Send>> {
|
||||
match arg_t.as_str() {
|
||||
@@ -489,7 +497,9 @@ fn convert_vec_val(
|
||||
.unwrap_or_default()
|
||||
})
|
||||
})?)),
|
||||
"jsonb" | "json" => Ok(Box::new(vec.clone().into_iter().map(Some).collect_vec())),
|
||||
"jsonb" | "json" => Ok(Box::new(
|
||||
vec.map(|v| v.clone().into_iter().map(Some).collect_vec()),
|
||||
)),
|
||||
"bytea" => Ok(Box::new(map_as_single_type(vec, |v| {
|
||||
v.as_str().map(|x| {
|
||||
engine::general_purpose::STANDARD
|
||||
@@ -512,9 +522,31 @@ fn convert_val(
|
||||
match value {
|
||||
Value::Array(vec) if arg_t.ends_with("[]") => {
|
||||
let arg_t = arg_t.trim_end_matches("[]").to_string();
|
||||
convert_vec_val(vec, &arg_t)
|
||||
convert_vec_val(Some(vec), &arg_t)
|
||||
}
|
||||
Value::Null => Ok(Box::new(None::<bool>)),
|
||||
Value::Null if arg_t.ends_with("[]") => {
|
||||
let arg_t = arg_t.trim_end_matches("[]").to_string();
|
||||
convert_vec_val(None, &arg_t)
|
||||
}
|
||||
Value::Null => match arg_t.as_str() {
|
||||
"bool" | "boolean" => Ok(Box::new(None::<bool>)),
|
||||
"char" | "character" => Ok(Box::new(None::<i8>)),
|
||||
"smallint" | "smallserial" | "int2" | "serial2" => Ok(Box::new(None::<i16>)),
|
||||
"int" | "integer" | "int4" | "serial" => Ok(Box::new(None::<i32>)),
|
||||
"numeric" | "decimal" => Ok(Box::new(None::<Decimal>)),
|
||||
"oid" => Ok(Box::new(None::<u32>)),
|
||||
"bigint" | "bigserial" | "int8" | "serial8" => Ok(Box::new(None::<i64>)),
|
||||
"real" | "float4" => Ok(Box::new(None::<f32>)),
|
||||
"double" | "float8" => Ok(Box::new(None::<f64>)),
|
||||
"uuid" => Ok(Box::new(None::<Uuid>)),
|
||||
"date" => Ok(Box::new(None::<chrono::NaiveDate>)),
|
||||
"time" | "timetz" => Ok(Box::new(None::<chrono::NaiveTime>)),
|
||||
"timestamp" | "timestamptz" => Ok(Box::new(None::<chrono::NaiveDateTime>)),
|
||||
"jsonb" | "json" => Ok(Box::new(None::<Option<Value>>)),
|
||||
"bytea" => Ok(Box::new(None::<Vec<u8>>)),
|
||||
"text" | "varchar" => Ok(Box::new(None::<String>)),
|
||||
_ => Err(anyhow::anyhow!("Unsupported JSON null type"))?,
|
||||
},
|
||||
Value::Bool(b) => Ok(Box::new(b.clone())),
|
||||
Value::Number(n) if matches!(typ, Typ::Str(_)) => Ok(Box::new(n.to_string())),
|
||||
Value::Number(n) if arg_t == "char" && n.is_i64() => {
|
||||
@@ -583,6 +615,11 @@ fn convert_val(
|
||||
.unwrap_or(vec![]);
|
||||
Ok(Box::new(bytes))
|
||||
}
|
||||
Value::Object(_) if arg_t == "text" || arg_t == "varchar" => {
|
||||
Ok(Box::new(serde_json::to_string(value).map_err(|err| {
|
||||
Error::ExecutionErr(format!("Failed to convert JSON to text: {}", err))
|
||||
})?))
|
||||
}
|
||||
Value::Object(_) => Ok(Box::new(value.clone())),
|
||||
Value::String(s) => Ok(Box::new(s.clone())),
|
||||
_ => Err(Error::ExecutionErr(format!(
|
||||
|
||||
@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
|
||||
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
|
||||
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
|
||||
|
||||
export const VERSION = "v1.424.0";
|
||||
export const VERSION = "v1.425.1";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
@@ -54,7 +54,7 @@ export const OpenAPI: OpenAPIConfig = {
|
||||
PASSWORD: undefined,
|
||||
TOKEN: getEnv("WM_TOKEN"),
|
||||
USERNAME: undefined,
|
||||
VERSION: '1.407.2',
|
||||
VERSION: '1.425.1',
|
||||
WITH_CREDENTIALS: true,
|
||||
interceptors: {
|
||||
request: new Interceptors(),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,10 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
|
||||
export type AiResource = {
|
||||
path: string;
|
||||
provider: string;
|
||||
};
|
||||
|
||||
export type Script = {
|
||||
workspace_id?: string;
|
||||
hash: string;
|
||||
@@ -257,18 +262,21 @@ export type TruncatedToken = {
|
||||
created_at: string;
|
||||
last_used_at: string;
|
||||
scopes?: Array<(string)>;
|
||||
email?: string;
|
||||
};
|
||||
|
||||
export type NewToken = {
|
||||
label?: string;
|
||||
expiration?: string;
|
||||
scopes?: Array<(string)>;
|
||||
workspace_id?: string;
|
||||
};
|
||||
|
||||
export type NewTokenImpersonate = {
|
||||
label?: string;
|
||||
expiration?: string;
|
||||
impersonate_email: string;
|
||||
workspace_id?: string;
|
||||
};
|
||||
|
||||
export type ListableVariable = {
|
||||
@@ -317,7 +325,7 @@ export type AuditLog = {
|
||||
id: number;
|
||||
timestamp: string;
|
||||
username: string;
|
||||
operation: 'jobs.run' | 'jobs.run.script' | 'jobs.run.preview' | 'jobs.run.flow' | 'jobs.run.flow_preview' | 'jobs.run.script_hub' | 'jobs.run.dependencies' | 'jobs.run.identity' | 'jobs.run.noop' | 'jobs.flow_dependencies' | 'jobs' | 'jobs.cancel' | 'jobs.force_cancel' | 'jobs.disapproval' | 'jobs.delete' | 'account.delete' | 'openai.request' | 'resources.create' | 'resources.update' | 'resources.delete' | 'resource_types.create' | 'resource_types.update' | 'resource_types.delete' | 'schedule.create' | 'schedule.setenabled' | 'schedule.edit' | 'schedule.delete' | 'scripts.create' | 'scripts.update' | 'scripts.archive' | 'scripts.delete' | 'users.create' | 'users.delete' | 'users.update' | 'users.login' | 'users.logout' | 'users.accept_invite' | 'users.decline_invite' | 'users.token.create' | 'users.token.delete' | 'users.add_to_workspace' | 'users.add_global' | 'users.setpassword' | 'users.impersonate' | 'users.leave_workspace' | 'oauth.login' | 'oauth.signup' | 'variables.create' | 'variables.delete' | 'variables.update' | 'flows.create' | 'flows.update' | 'flows.delete' | 'flows.archive' | 'apps.create' | 'apps.update' | 'apps.delete' | 'folder.create' | 'folder.update' | 'folder.delete' | 'folder.add_owner' | 'folder.remove_owner' | 'group.create' | 'group.delete' | 'group.edit' | 'group.adduser' | 'group.removeuser' | 'igroup.create' | 'igroup.delete' | 'igroup.adduser' | 'igroup.removeuser' | 'variables.decrypt_secret' | 'workspaces.edit_command_script' | 'workspaces.edit_deploy_to' | 'workspaces.edit_auto_invite_domain' | 'workspaces.edit_webhook' | 'workspaces.edit_copilot_config' | 'workspaces.edit_error_handler' | 'workspaces.create' | 'workspaces.update' | 'workspaces.archive' | 'workspaces.unarchive' | 'workspaces.delete';
|
||||
operation: 'jobs.run' | 'jobs.run.script' | 'jobs.run.preview' | 'jobs.run.flow' | 'jobs.run.flow_preview' | 'jobs.run.script_hub' | 'jobs.run.dependencies' | 'jobs.run.identity' | 'jobs.run.noop' | 'jobs.flow_dependencies' | 'jobs' | 'jobs.cancel' | 'jobs.force_cancel' | 'jobs.disapproval' | 'jobs.delete' | 'account.delete' | 'ai.request' | 'resources.create' | 'resources.update' | 'resources.delete' | 'resource_types.create' | 'resource_types.update' | 'resource_types.delete' | 'schedule.create' | 'schedule.setenabled' | 'schedule.edit' | 'schedule.delete' | 'scripts.create' | 'scripts.update' | 'scripts.archive' | 'scripts.delete' | 'users.create' | 'users.delete' | 'users.update' | 'users.login' | 'users.login_failure' | 'users.logout' | 'users.accept_invite' | 'users.decline_invite' | 'users.token.create' | 'users.token.delete' | 'users.add_to_workspace' | 'users.add_global' | 'users.setpassword' | 'users.impersonate' | 'users.leave_workspace' | 'oauth.login' | 'oauth.login_failure' | 'oauth.signup' | 'variables.create' | 'variables.delete' | 'variables.update' | 'flows.create' | 'flows.update' | 'flows.delete' | 'flows.archive' | 'apps.create' | 'apps.update' | 'apps.delete' | 'folder.create' | 'folder.update' | 'folder.delete' | 'folder.add_owner' | 'folder.remove_owner' | 'group.create' | 'group.delete' | 'group.edit' | 'group.adduser' | 'group.removeuser' | 'igroup.create' | 'igroup.delete' | 'igroup.adduser' | 'igroup.removeuser' | 'variables.decrypt_secret' | 'workspaces.edit_command_script' | 'workspaces.edit_deploy_to' | 'workspaces.edit_auto_invite_domain' | 'workspaces.edit_webhook' | 'workspaces.edit_copilot_config' | 'workspaces.edit_error_handler' | 'workspaces.create' | 'workspaces.update' | 'workspaces.archive' | 'workspaces.unarchive' | 'workspaces.delete';
|
||||
action_kind: 'Created' | 'Updated' | 'Delete' | 'Execute';
|
||||
resource?: string;
|
||||
parameters?: {
|
||||
@@ -325,7 +333,7 @@ export type AuditLog = {
|
||||
};
|
||||
};
|
||||
|
||||
export type operation = 'jobs.run' | 'jobs.run.script' | 'jobs.run.preview' | 'jobs.run.flow' | 'jobs.run.flow_preview' | 'jobs.run.script_hub' | 'jobs.run.dependencies' | 'jobs.run.identity' | 'jobs.run.noop' | 'jobs.flow_dependencies' | 'jobs' | 'jobs.cancel' | 'jobs.force_cancel' | 'jobs.disapproval' | 'jobs.delete' | 'account.delete' | 'openai.request' | 'resources.create' | 'resources.update' | 'resources.delete' | 'resource_types.create' | 'resource_types.update' | 'resource_types.delete' | 'schedule.create' | 'schedule.setenabled' | 'schedule.edit' | 'schedule.delete' | 'scripts.create' | 'scripts.update' | 'scripts.archive' | 'scripts.delete' | 'users.create' | 'users.delete' | 'users.update' | 'users.login' | 'users.logout' | 'users.accept_invite' | 'users.decline_invite' | 'users.token.create' | 'users.token.delete' | 'users.add_to_workspace' | 'users.add_global' | 'users.setpassword' | 'users.impersonate' | 'users.leave_workspace' | 'oauth.login' | 'oauth.signup' | 'variables.create' | 'variables.delete' | 'variables.update' | 'flows.create' | 'flows.update' | 'flows.delete' | 'flows.archive' | 'apps.create' | 'apps.update' | 'apps.delete' | 'folder.create' | 'folder.update' | 'folder.delete' | 'folder.add_owner' | 'folder.remove_owner' | 'group.create' | 'group.delete' | 'group.edit' | 'group.adduser' | 'group.removeuser' | 'igroup.create' | 'igroup.delete' | 'igroup.adduser' | 'igroup.removeuser' | 'variables.decrypt_secret' | 'workspaces.edit_command_script' | 'workspaces.edit_deploy_to' | 'workspaces.edit_auto_invite_domain' | 'workspaces.edit_webhook' | 'workspaces.edit_copilot_config' | 'workspaces.edit_error_handler' | 'workspaces.create' | 'workspaces.update' | 'workspaces.archive' | 'workspaces.unarchive' | 'workspaces.delete';
|
||||
export type operation = 'jobs.run' | 'jobs.run.script' | 'jobs.run.preview' | 'jobs.run.flow' | 'jobs.run.flow_preview' | 'jobs.run.script_hub' | 'jobs.run.dependencies' | 'jobs.run.identity' | 'jobs.run.noop' | 'jobs.flow_dependencies' | 'jobs' | 'jobs.cancel' | 'jobs.force_cancel' | 'jobs.disapproval' | 'jobs.delete' | 'account.delete' | 'ai.request' | 'resources.create' | 'resources.update' | 'resources.delete' | 'resource_types.create' | 'resource_types.update' | 'resource_types.delete' | 'schedule.create' | 'schedule.setenabled' | 'schedule.edit' | 'schedule.delete' | 'scripts.create' | 'scripts.update' | 'scripts.archive' | 'scripts.delete' | 'users.create' | 'users.delete' | 'users.update' | 'users.login' | 'users.login_failure' | 'users.logout' | 'users.accept_invite' | 'users.decline_invite' | 'users.token.create' | 'users.token.delete' | 'users.add_to_workspace' | 'users.add_global' | 'users.setpassword' | 'users.impersonate' | 'users.leave_workspace' | 'oauth.login' | 'oauth.login_failure' | 'oauth.signup' | 'variables.create' | 'variables.delete' | 'variables.update' | 'flows.create' | 'flows.update' | 'flows.delete' | 'flows.archive' | 'apps.create' | 'apps.update' | 'apps.delete' | 'folder.create' | 'folder.update' | 'folder.delete' | 'folder.add_owner' | 'folder.remove_owner' | 'group.create' | 'group.delete' | 'group.edit' | 'group.adduser' | 'group.removeuser' | 'igroup.create' | 'igroup.delete' | 'igroup.adduser' | 'igroup.removeuser' | 'variables.decrypt_secret' | 'workspaces.edit_command_script' | 'workspaces.edit_deploy_to' | 'workspaces.edit_auto_invite_domain' | 'workspaces.edit_webhook' | 'workspaces.edit_copilot_config' | 'workspaces.edit_error_handler' | 'workspaces.create' | 'workspaces.update' | 'workspaces.archive' | 'workspaces.unarchive' | 'workspaces.delete';
|
||||
|
||||
export type action_kind = 'Created' | 'Updated' | 'Delete' | 'Execute';
|
||||
|
||||
@@ -542,6 +550,11 @@ export type HttpTrigger = {
|
||||
edited_at: string;
|
||||
script_path: string;
|
||||
route_path: string;
|
||||
static_asset_config?: {
|
||||
s3: string;
|
||||
storage?: string;
|
||||
filename?: string;
|
||||
};
|
||||
is_flow: boolean;
|
||||
extra_perms: {
|
||||
[key: string]: (boolean);
|
||||
@@ -559,6 +572,11 @@ export type NewHttpTrigger = {
|
||||
path: string;
|
||||
script_path: string;
|
||||
route_path: string;
|
||||
static_asset_config?: {
|
||||
s3: string;
|
||||
storage?: string;
|
||||
filename?: string;
|
||||
};
|
||||
is_flow: boolean;
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
is_async: boolean;
|
||||
@@ -569,12 +587,89 @@ export type EditHttpTrigger = {
|
||||
path: string;
|
||||
script_path: string;
|
||||
route_path?: string;
|
||||
static_asset_config?: {
|
||||
s3: string;
|
||||
storage?: string;
|
||||
filename?: string;
|
||||
};
|
||||
is_flow: boolean;
|
||||
http_method: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
||||
is_async: boolean;
|
||||
requires_auth: boolean;
|
||||
};
|
||||
|
||||
export type TriggersCount = {
|
||||
primary_schedule?: {
|
||||
schedule?: string;
|
||||
};
|
||||
schedule_count?: number;
|
||||
http_routes_count?: number;
|
||||
webhook_count?: number;
|
||||
email_count?: number;
|
||||
websocket_count?: number;
|
||||
};
|
||||
|
||||
export type WebsocketTrigger = {
|
||||
path: string;
|
||||
edited_by: string;
|
||||
edited_at: string;
|
||||
script_path: string;
|
||||
url: string;
|
||||
is_flow: boolean;
|
||||
extra_perms: {
|
||||
[key: string]: (boolean);
|
||||
};
|
||||
email: string;
|
||||
workspace_id: string;
|
||||
server_id?: string;
|
||||
last_server_ping?: string;
|
||||
error?: string;
|
||||
enabled: boolean;
|
||||
filters: Array<{
|
||||
key: string;
|
||||
value: unknown;
|
||||
}>;
|
||||
initial_messages: Array<WebsocketTriggerInitialMessage>;
|
||||
url_runnable_args: ScriptArgs;
|
||||
};
|
||||
|
||||
export type NewWebsocketTrigger = {
|
||||
path: string;
|
||||
script_path: string;
|
||||
is_flow: boolean;
|
||||
url: string;
|
||||
enabled?: boolean;
|
||||
filters: Array<{
|
||||
key: string;
|
||||
value: unknown;
|
||||
}>;
|
||||
initial_messages: Array<WebsocketTriggerInitialMessage>;
|
||||
url_runnable_args: ScriptArgs;
|
||||
};
|
||||
|
||||
export type EditWebsocketTrigger = {
|
||||
url: string;
|
||||
path: string;
|
||||
script_path: string;
|
||||
is_flow: boolean;
|
||||
filters: Array<{
|
||||
key: string;
|
||||
value: unknown;
|
||||
}>;
|
||||
initial_messages: Array<WebsocketTriggerInitialMessage>;
|
||||
url_runnable_args: ScriptArgs;
|
||||
};
|
||||
|
||||
export type WebsocketTriggerInitialMessage = {
|
||||
raw_message: string;
|
||||
} | {
|
||||
runnable_result: {
|
||||
path: string;
|
||||
args: ScriptArgs;
|
||||
is_flow: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type Group = {
|
||||
name: string;
|
||||
summary?: string;
|
||||
@@ -660,6 +755,7 @@ export type GlobalUserInfo = {
|
||||
name?: string;
|
||||
company?: string;
|
||||
username?: string;
|
||||
operator_only?: boolean;
|
||||
};
|
||||
|
||||
export type login_type = 'password' | 'github';
|
||||
@@ -722,6 +818,9 @@ export type Policy = {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
s3_inputs?: Array<{
|
||||
[key: string]: unknown;
|
||||
}>;
|
||||
execution_mode?: 'viewer' | 'publisher' | 'anonymous';
|
||||
on_behalf_of?: string;
|
||||
on_behalf_of_email?: string;
|
||||
@@ -968,6 +1067,46 @@ export type JobSearchHit = {
|
||||
dancer?: string;
|
||||
};
|
||||
|
||||
export type LogSearchHit = {
|
||||
dancer?: string;
|
||||
};
|
||||
|
||||
export type AutoscalingEvent = {
|
||||
id?: number;
|
||||
worker_group?: string;
|
||||
event_type?: string;
|
||||
desired_workers?: number;
|
||||
reason?: string;
|
||||
applied_at?: string;
|
||||
};
|
||||
|
||||
export type CriticalAlert = {
|
||||
/**
|
||||
* Unique identifier for the alert
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Type of alert (e.g., critical_error)
|
||||
*/
|
||||
alert_type?: string;
|
||||
/**
|
||||
* The message content of the alert
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* Time when the alert was created
|
||||
*/
|
||||
created_at?: string;
|
||||
/**
|
||||
* Acknowledgment status of the alert, can be true, false, or null if not set
|
||||
*/
|
||||
acknowledged?: (boolean) | null;
|
||||
/**
|
||||
* Workspace id if the alert is in the scope of a workspace
|
||||
*/
|
||||
workspace_id?: (string) | null;
|
||||
};
|
||||
|
||||
export type OpenFlow = {
|
||||
summary: string;
|
||||
description?: string;
|
||||
@@ -1073,6 +1212,7 @@ export type RawScript = {
|
||||
concurrent_limit?: number;
|
||||
concurrency_time_window_s?: number;
|
||||
custom_concurrency_key?: string;
|
||||
is_trigger?: boolean;
|
||||
};
|
||||
|
||||
export type language2 = 'deno' | 'bun' | 'python3' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'php';
|
||||
@@ -1085,6 +1225,7 @@ export type PathScript = {
|
||||
hash?: string;
|
||||
type: 'script';
|
||||
tag_override?: string;
|
||||
is_trigger?: boolean;
|
||||
};
|
||||
|
||||
export type PathFlow = {
|
||||
@@ -1518,6 +1659,30 @@ export type SetPasswordData = {
|
||||
|
||||
export type SetPasswordResponse = (string);
|
||||
|
||||
export type SetPasswordForUserData = {
|
||||
/**
|
||||
* set password
|
||||
*/
|
||||
requestBody: {
|
||||
password: string;
|
||||
};
|
||||
user: string;
|
||||
};
|
||||
|
||||
export type SetPasswordForUserResponse = (string);
|
||||
|
||||
export type SetLoginTypeForUserData = {
|
||||
/**
|
||||
* set login type
|
||||
*/
|
||||
requestBody: {
|
||||
login_type: string;
|
||||
};
|
||||
user: string;
|
||||
};
|
||||
|
||||
export type SetLoginTypeForUserResponse = (string);
|
||||
|
||||
export type CreateUserGloballyData = {
|
||||
/**
|
||||
* user info
|
||||
@@ -1675,6 +1840,7 @@ export type TestSmtpData = {
|
||||
port: number;
|
||||
from: string;
|
||||
tls_implicit: boolean;
|
||||
disable_tls: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1693,6 +1859,25 @@ export type TestCriticalChannelsData = {
|
||||
|
||||
export type TestCriticalChannelsResponse = (string);
|
||||
|
||||
export type GetCriticalAlertsData = {
|
||||
acknowledged?: (boolean) | null;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
};
|
||||
|
||||
export type GetCriticalAlertsResponse = (Array<CriticalAlert>);
|
||||
|
||||
export type AcknowledgeCriticalAlertData = {
|
||||
/**
|
||||
* The ID of the critical alert to acknowledge
|
||||
*/
|
||||
id: number;
|
||||
};
|
||||
|
||||
export type AcknowledgeCriticalAlertResponse = (string);
|
||||
|
||||
export type AcknowledgeAllCriticalAlertsResponse = (string);
|
||||
|
||||
export type TestLicenseKeyData = {
|
||||
/**
|
||||
* test license key
|
||||
@@ -1917,6 +2102,10 @@ export type ExistsEmailData = {
|
||||
export type ExistsEmailResponse = (boolean);
|
||||
|
||||
export type ListUsersAsSuperAdminData = {
|
||||
/**
|
||||
* filter only active users
|
||||
*/
|
||||
activeOnly?: boolean;
|
||||
/**
|
||||
* which page to return (start at 1, default 1)
|
||||
*/
|
||||
@@ -1952,7 +2141,7 @@ export type GetSettingsResponse = ({
|
||||
customer_id?: string;
|
||||
webhook?: string;
|
||||
deploy_to?: string;
|
||||
openai_resource_path?: string;
|
||||
ai_resource?: AiResource;
|
||||
code_completion_enabled: boolean;
|
||||
error_handler?: string;
|
||||
error_handler_extra_args?: ScriptArgs;
|
||||
@@ -1962,6 +2151,7 @@ export type GetSettingsResponse = ({
|
||||
deploy_ui?: WorkspaceDeployUISettings;
|
||||
default_app?: string;
|
||||
default_scripts?: WorkspaceDefaultScripts;
|
||||
mute_critical_alerts?: boolean;
|
||||
});
|
||||
|
||||
export type GetDeployToData = {
|
||||
@@ -2070,7 +2260,7 @@ export type EditCopilotConfigData = {
|
||||
* WorkspaceCopilotConfig
|
||||
*/
|
||||
requestBody: {
|
||||
openai_resource_path?: string;
|
||||
ai_resource?: AiResource;
|
||||
code_completion_enabled: boolean;
|
||||
};
|
||||
workspace: string;
|
||||
@@ -2083,7 +2273,8 @@ export type GetCopilotInfoData = {
|
||||
};
|
||||
|
||||
export type GetCopilotInfoResponse = ({
|
||||
exists_openai_resource_path: boolean;
|
||||
ai_provider: string;
|
||||
exists_ai_resource: boolean;
|
||||
code_completion_enabled: boolean;
|
||||
});
|
||||
|
||||
@@ -2219,6 +2410,15 @@ export type GetWorkspaceUsageData = {
|
||||
|
||||
export type GetWorkspaceUsageResponse = (number);
|
||||
|
||||
export type GetUsedTriggersData = {
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetUsedTriggersResponse = ({
|
||||
http_routes_used: boolean;
|
||||
websocket_used: boolean;
|
||||
});
|
||||
|
||||
export type ListUsersData = {
|
||||
workspace: string;
|
||||
};
|
||||
@@ -2382,6 +2582,46 @@ export type ListContextualVariablesData = {
|
||||
|
||||
export type ListContextualVariablesResponse = (Array<ContextualVariable>);
|
||||
|
||||
export type WorkspaceGetCriticalAlertsData = {
|
||||
acknowledged?: (boolean) | null;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type WorkspaceGetCriticalAlertsResponse = (Array<CriticalAlert>);
|
||||
|
||||
export type WorkspaceAcknowledgeCriticalAlertData = {
|
||||
/**
|
||||
* The ID of the critical alert to acknowledge
|
||||
*/
|
||||
id: number;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type WorkspaceAcknowledgeCriticalAlertResponse = (string);
|
||||
|
||||
export type WorkspaceAcknowledgeAllCriticalAlertsData = {
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type WorkspaceAcknowledgeAllCriticalAlertsResponse = (string);
|
||||
|
||||
export type WorkspaceMuteCriticalAlertsUiData = {
|
||||
/**
|
||||
* Boolean flag to mute critical alerts.
|
||||
*/
|
||||
requestBody: {
|
||||
/**
|
||||
* Whether critical alerts should be muted.
|
||||
*/
|
||||
mute_critical_alerts?: boolean;
|
||||
};
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type WorkspaceMuteCriticalAlertsUiResponse = (string);
|
||||
|
||||
export type LoginWithOauthData = {
|
||||
clientName: string;
|
||||
/**
|
||||
@@ -2474,7 +2714,10 @@ export type DisconnectSlackData = {
|
||||
export type DisconnectSlackResponse = (string);
|
||||
|
||||
export type ListOauthLoginsResponse = ({
|
||||
oauth: Array<(string)>;
|
||||
oauth: Array<{
|
||||
type: string;
|
||||
display_name?: string;
|
||||
}>;
|
||||
saml?: string;
|
||||
});
|
||||
|
||||
@@ -3011,6 +3254,20 @@ export type GetScriptByPathData = {
|
||||
|
||||
export type GetScriptByPathResponse = (Script);
|
||||
|
||||
export type GetTriggersCountOfScriptData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetTriggersCountOfScriptResponse = (TriggersCount);
|
||||
|
||||
export type ListTokensOfScriptData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type ListTokensOfScriptResponse = (Array<TruncatedToken>);
|
||||
|
||||
export type GetScriptByPathWithDraftData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
@@ -3025,6 +3282,13 @@ export type GetScriptHistoryByPathData = {
|
||||
|
||||
export type GetScriptHistoryByPathResponse = (Array<ScriptHistory>);
|
||||
|
||||
export type GetScriptLatestVersionData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetScriptLatestVersionResponse = (ScriptHistory);
|
||||
|
||||
export type UpdateScriptHistoryData = {
|
||||
hash: string;
|
||||
path: string;
|
||||
@@ -3378,6 +3642,13 @@ export type GetFlowHistoryData = {
|
||||
|
||||
export type GetFlowHistoryResponse = (Array<FlowVersion>);
|
||||
|
||||
export type GetFlowLatestVersionData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetFlowLatestVersionResponse = (FlowVersion);
|
||||
|
||||
export type GetFlowVersionData = {
|
||||
path: string;
|
||||
version: number;
|
||||
@@ -3408,6 +3679,20 @@ export type GetFlowByPathData = {
|
||||
|
||||
export type GetFlowByPathResponse = (Flow);
|
||||
|
||||
export type GetTriggersCountOfFlowData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetTriggersCountOfFlowResponse = (TriggersCount);
|
||||
|
||||
export type ListTokensOfFlowData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type ListTokensOfFlowResponse = (Array<TruncatedToken>);
|
||||
|
||||
export type ToggleWorkspaceErrorHandlerForFlowData = {
|
||||
path: string;
|
||||
/**
|
||||
@@ -3637,6 +3922,13 @@ export type GetAppHistoryByPathData = {
|
||||
|
||||
export type GetAppHistoryByPathResponse = (Array<AppHistory>);
|
||||
|
||||
export type GetAppLatestVersionData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetAppLatestVersionResponse = (AppHistory);
|
||||
|
||||
export type UpdateAppHistoryData = {
|
||||
id: number;
|
||||
/**
|
||||
@@ -4099,6 +4391,16 @@ export type GetCompletedCountResponse = ({
|
||||
database_length: number;
|
||||
});
|
||||
|
||||
export type CountCompletedJobsData = {
|
||||
allWorkspaces?: boolean;
|
||||
completedAfterSAgo?: number;
|
||||
success?: boolean;
|
||||
tags?: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type CountCompletedJobsResponse = (number);
|
||||
|
||||
export type ListFilteredUuidsData = {
|
||||
/**
|
||||
* get jobs from all workspaces (only valid if request come from the `admins` workspace)
|
||||
@@ -4888,11 +5190,80 @@ export type ExistsRouteData = {
|
||||
|
||||
export type ExistsRouteResponse = (boolean);
|
||||
|
||||
export type UsedData = {
|
||||
export type CreateWebsocketTriggerData = {
|
||||
/**
|
||||
* new websocket trigger
|
||||
*/
|
||||
requestBody: NewWebsocketTrigger;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type UsedResponse = (boolean);
|
||||
export type CreateWebsocketTriggerResponse = (string);
|
||||
|
||||
export type UpdateWebsocketTriggerData = {
|
||||
path: string;
|
||||
/**
|
||||
* updated trigger
|
||||
*/
|
||||
requestBody: EditWebsocketTrigger;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type UpdateWebsocketTriggerResponse = (string);
|
||||
|
||||
export type DeleteWebsocketTriggerData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type DeleteWebsocketTriggerResponse = (string);
|
||||
|
||||
export type GetWebsocketTriggerData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type GetWebsocketTriggerResponse = (WebsocketTrigger);
|
||||
|
||||
export type ListWebsocketTriggersData = {
|
||||
isFlow?: boolean;
|
||||
/**
|
||||
* which page to return (start at 1, default 1)
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* filter by path
|
||||
*/
|
||||
path?: string;
|
||||
pathStart?: string;
|
||||
/**
|
||||
* number of items to return for a given page (default 30, max 100)
|
||||
*/
|
||||
perPage?: number;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type ListWebsocketTriggersResponse = (Array<WebsocketTrigger>);
|
||||
|
||||
export type ExistsWebsocketTriggerData = {
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type ExistsWebsocketTriggerResponse = (boolean);
|
||||
|
||||
export type SetWebsocketTriggerEnabledData = {
|
||||
path: string;
|
||||
/**
|
||||
* updated websocket trigger enable
|
||||
*/
|
||||
requestBody: {
|
||||
enabled: boolean;
|
||||
};
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export type SetWebsocketTriggerEnabledResponse = (string);
|
||||
|
||||
export type ListInstanceGroupsResponse = (Array<InstanceGroup>);
|
||||
|
||||
@@ -5201,6 +5572,10 @@ export type GetQueueMetricsResponse = (Array<{
|
||||
}>;
|
||||
}>);
|
||||
|
||||
export type GetCountsOfJobsWaitingPerTagResponse = ({
|
||||
[key: string]: (number);
|
||||
});
|
||||
|
||||
export type ListWorkerGroupsResponse = (Array<{
|
||||
name: string;
|
||||
config: unknown;
|
||||
@@ -5230,8 +5605,14 @@ export type DeleteConfigResponse = (string);
|
||||
|
||||
export type ListConfigsResponse = (Array<Config>);
|
||||
|
||||
export type ListAutoscalingEventsData = {
|
||||
workerGroup: string;
|
||||
};
|
||||
|
||||
export type ListAutoscalingEventsResponse = (Array<AutoscalingEvent>);
|
||||
|
||||
export type GetGranularAclsData = {
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger';
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
|
||||
path: string;
|
||||
workspace: string;
|
||||
};
|
||||
@@ -5241,7 +5622,7 @@ export type GetGranularAclsResponse = ({
|
||||
});
|
||||
|
||||
export type AddGranularAclsData = {
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger';
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
|
||||
path: string;
|
||||
/**
|
||||
* acl to add
|
||||
@@ -5256,7 +5637,7 @@ export type AddGranularAclsData = {
|
||||
export type AddGranularAclsResponse = (string);
|
||||
|
||||
export type RemoveGranularAclsData = {
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger';
|
||||
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
|
||||
path: string;
|
||||
/**
|
||||
* acl to add
|
||||
@@ -5569,6 +5950,8 @@ export type MoveS3FileData = {
|
||||
export type MoveS3FileResponse = (unknown);
|
||||
|
||||
export type FileUploadData = {
|
||||
contentDisposition?: string;
|
||||
contentType?: string;
|
||||
fileExtension?: string;
|
||||
fileKey?: string;
|
||||
/**
|
||||
@@ -5817,4 +6200,44 @@ export type SearchJobsIndexResponse = ({
|
||||
* the jobs that matched the query
|
||||
*/
|
||||
hits?: Array<JobSearchHit>;
|
||||
});
|
||||
|
||||
export type SearchLogsIndexData = {
|
||||
hostname: string;
|
||||
maxTs?: string;
|
||||
minTs?: string;
|
||||
mode: string;
|
||||
searchQuery: string;
|
||||
workerGroup?: string;
|
||||
};
|
||||
|
||||
export type SearchLogsIndexResponse = ({
|
||||
/**
|
||||
* a list of the terms that couldn't be parsed (and thus ignored)
|
||||
*/
|
||||
query_parse_errors?: Array<(string)>;
|
||||
/**
|
||||
* log files that matched the query
|
||||
*/
|
||||
hits?: Array<LogSearchHit>;
|
||||
});
|
||||
|
||||
export type CountSearchLogsIndexData = {
|
||||
hosts: string;
|
||||
maxTs?: string;
|
||||
minTs?: string;
|
||||
searchQuery: string;
|
||||
};
|
||||
|
||||
export type CountSearchLogsIndexResponse = ({
|
||||
/**
|
||||
* a list of the terms that couldn't be parsed (and thus ignored)
|
||||
*/
|
||||
query_parse_errors?: Array<(string)>;
|
||||
/**
|
||||
* count of log lines that matched the query per hostname
|
||||
*/
|
||||
count_per_host?: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
});
|
||||
@@ -60,7 +60,7 @@ export {
|
||||
// }
|
||||
// });
|
||||
|
||||
export const VERSION = "1.424.0";
|
||||
export const VERSION = "1.425.1";
|
||||
|
||||
const command = new Command()
|
||||
.name("wmill")
|
||||
|
||||
@@ -4,10 +4,10 @@ import { colors } from "./deps.ts";
|
||||
import { yamlParseFile } from "./deps.ts";
|
||||
import { log } from "./deps.ts";
|
||||
import { compareInstanceObjects, InstanceSyncOptions } from "./instance.ts";
|
||||
import { isSuperset, GlobalOptions } from "./types.ts";
|
||||
import { isSuperset } from "./types.ts";
|
||||
import { deepEqual } from "./utils.ts";
|
||||
import * as wmill from "./gen/services.gen.ts";
|
||||
import { Config, GlobalSetting } from "./gen/types.gen.ts";
|
||||
import { AiResource, Config, GlobalSetting } from "./gen/types.gen.ts";
|
||||
import { removeWorkerPrefix } from "./worker_groups.ts";
|
||||
import process from "node:process";
|
||||
|
||||
@@ -24,7 +24,7 @@ export interface SimplifiedSettings {
|
||||
error_handler?: string;
|
||||
error_handler_extra_args?: any;
|
||||
error_handler_muted_on_cancel?: boolean;
|
||||
openai_resource_path?: string;
|
||||
ai_resource?: AiResource;
|
||||
code_completion_enabled: boolean;
|
||||
large_file_storage?: any;
|
||||
git_sync?: any;
|
||||
@@ -80,7 +80,7 @@ export async function pushWorkspaceSettings(
|
||||
error_handler_extra_args: remoteSettings.error_handler_extra_args,
|
||||
error_handler_muted_on_cancel:
|
||||
remoteSettings.error_handler_muted_on_cancel,
|
||||
openai_resource_path: remoteSettings.openai_resource_path,
|
||||
ai_resource: remoteSettings.ai_resource,
|
||||
code_completion_enabled: remoteSettings.code_completion_enabled,
|
||||
large_file_storage: remoteSettings.large_file_storage,
|
||||
git_sync: remoteSettings.git_sync,
|
||||
@@ -153,14 +153,14 @@ export async function pushWorkspaceSettings(
|
||||
}
|
||||
}
|
||||
if (
|
||||
localSettings.openai_resource_path !== settings.openai_resource_path ||
|
||||
localSettings.ai_resource !== settings.ai_resource ||
|
||||
localSettings.code_completion_enabled !== settings.code_completion_enabled
|
||||
) {
|
||||
log.debug(`Updating openai settings...`);
|
||||
await wmill.editCopilotConfig({
|
||||
workspace,
|
||||
requestBody: {
|
||||
openai_resource_path: localSettings.openai_resource_path,
|
||||
ai_resource: localSettings.ai_resource,
|
||||
code_completion_enabled: localSettings.code_completion_enabled,
|
||||
},
|
||||
});
|
||||
|
||||
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.424.0",
|
||||
"version": "1.425.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.424.0",
|
||||
"version": "1.425.1",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.32.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.424.0",
|
||||
"version": "1.425.1",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
cleanValueProperties,
|
||||
orderedJsonStringify,
|
||||
orderedYamlStringify,
|
||||
replaceFalseWithUndefined,
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import type { Script } from '$lib/gen'
|
||||
@@ -54,8 +55,9 @@
|
||||
diffViewer.closeDrawer()
|
||||
}
|
||||
|
||||
|
||||
function prepareDiff(data: Value) {
|
||||
const metadata = structuredClone(cleanValueProperties(data))
|
||||
const metadata = structuredClone(cleanValueProperties(replaceFalseWithUndefined(data)))
|
||||
const content = metadata['content']
|
||||
if (metadata['content'] !== undefined) {
|
||||
metadata['content'] = 'check content diff'
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
encodeState,
|
||||
formatCron,
|
||||
orderedJsonStringify,
|
||||
replaceFalseWithUndefined,
|
||||
sleep,
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
@@ -294,12 +295,21 @@
|
||||
// We need it for diff
|
||||
await syncWithDeployed()
|
||||
|
||||
// Handle through confirmation modal
|
||||
confirmCallback = async () => {
|
||||
if (
|
||||
deployedValue &&
|
||||
$flowStore &&
|
||||
orderedJsonStringify(deployedValue) ===
|
||||
orderedJsonStringify(replaceFalseWithUndefined({ ...$flowStore, path: $pathStore }))
|
||||
) {
|
||||
await saveFlow(deploymentMsg)
|
||||
} else {
|
||||
// Handle through confirmation modal
|
||||
confirmCallback = async () => {
|
||||
await saveFlow(deploymentMsg)
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
}
|
||||
async function syncWithDeployed() {
|
||||
@@ -308,18 +318,12 @@
|
||||
path: initialPath,
|
||||
withStarredInfo: true
|
||||
})
|
||||
deployedValue = {
|
||||
deployedValue = replaceFalseWithUndefined({
|
||||
...flow,
|
||||
starred: undefined,
|
||||
id: undefined,
|
||||
edited_at: undefined,
|
||||
edited_by: undefined,
|
||||
workspace_id: undefined,
|
||||
archived: undefined,
|
||||
same_worker: undefined,
|
||||
visible_to_runner_only: undefined,
|
||||
ws_error_handler_muted: undefined
|
||||
}
|
||||
workspace_id: undefined
|
||||
})
|
||||
deployedBy = flow.edited_by
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
encodeState,
|
||||
formatCron,
|
||||
orderedJsonStringify,
|
||||
replaceFalseWithUndefined,
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import Path from './Path.svelte'
|
||||
@@ -278,17 +279,28 @@
|
||||
// Fetch entire script, since we need it to show Diff
|
||||
await syncWithDeployed()
|
||||
|
||||
// Handle through confirmation modal
|
||||
confirmCallback = async () => {
|
||||
open = false
|
||||
if (actual_parent_hash) {
|
||||
await editScript(stay, actual_parent_hash, deployMsg)
|
||||
} else {
|
||||
sendUserToast('Could not fetch latest version of the script', true)
|
||||
if (
|
||||
deployedValue &&
|
||||
script &&
|
||||
orderedJsonStringify({ ...deployedValue, hash: undefined }) ===
|
||||
orderedJsonStringify(
|
||||
replaceFalseWithUndefined({ ...script, hash: undefined, parent_hash: undefined })
|
||||
)
|
||||
) {
|
||||
await editScript(stay, actual_parent_hash, deployMsg)
|
||||
} else {
|
||||
// Handle through confirmation modal
|
||||
confirmCallback = async () => {
|
||||
open = false
|
||||
if (actual_parent_hash) {
|
||||
await editScript(stay, actual_parent_hash, deployMsg)
|
||||
} else {
|
||||
sendUserToast('Could not fetch latest version of the script', true)
|
||||
}
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,20 +311,16 @@
|
||||
withStarredInfo: true
|
||||
})
|
||||
|
||||
deployedValue = {
|
||||
deployedValue = replaceFalseWithUndefined({
|
||||
...latestScript,
|
||||
starred: undefined,
|
||||
workspace_id: undefined,
|
||||
archived: undefined,
|
||||
created_at: undefined,
|
||||
created_by: undefined,
|
||||
deleted: undefined,
|
||||
extra_perms: undefined,
|
||||
is_template: undefined,
|
||||
lock: undefined,
|
||||
lock_error_logs: undefined,
|
||||
parent_hashes: undefined
|
||||
}
|
||||
})
|
||||
|
||||
deployedBy = latestScript.created_by
|
||||
}
|
||||
@@ -691,8 +699,11 @@
|
||||
</Label>
|
||||
<Label label="Path">
|
||||
<svelte:fragment slot="header">
|
||||
<Tooltip documentationLink="https://www.windmill.dev/docs/core_concepts/roles_and_permissions#path">
|
||||
The unique identifier of the script in the workspace that defines permissions
|
||||
<Tooltip
|
||||
documentationLink="https://www.windmill.dev/docs/core_concepts/roles_and_permissions#path"
|
||||
>
|
||||
The unique identifier of the script in the workspace that defines
|
||||
permissions
|
||||
</Tooltip>
|
||||
</svelte:fragment>
|
||||
<Path
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
import { offset, flip, shift } from 'svelte-floating-ui/dom'
|
||||
import ResolveStyle from '../helpers/ResolveStyle.svelte'
|
||||
import MultiSelect from '$lib/components/multiselect/MultiSelect.svelte'
|
||||
import type { ObjectOption } from '../../../multiselect/types'
|
||||
import { parseConfigOptions } from './utils'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
|
||||
export let id: string
|
||||
export let configuration: RichConfigurations
|
||||
export let customCss: ComponentCustomCSS<'multiselectcomponent'> | undefined = undefined
|
||||
export let id: string
|
||||
export let render: boolean
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
|
||||
@@ -30,55 +33,33 @@
|
||||
|
||||
const { app, worldStore, selectedComponent, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
let items: string[]
|
||||
|
||||
const resolvedConfig = initConfig(
|
||||
components['multiselectcomponent'].initialData.configuration,
|
||||
components['multiselectcomponentv2'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: [] as string[]
|
||||
})
|
||||
|
||||
let value: string[] | undefined = [...new Set(outputs?.result.peak())] as string[]
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(nvalue: string[]) {
|
||||
value = [...new Set(nvalue)]
|
||||
outputs?.result.set([...(value ?? [])])
|
||||
}
|
||||
}
|
||||
|
||||
$: resolvedConfig.items && handleItems()
|
||||
|
||||
function handleItems() {
|
||||
if (Array.isArray(resolvedConfig.items)) {
|
||||
items = resolvedConfig.items?.map((label) => {
|
||||
return typeof label === 'string' ? label : `NOT_STRING`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$: resolvedConfig.defaultItems && handleDefaultItems()
|
||||
|
||||
function handleDefaultItems() {
|
||||
if (Array.isArray(resolvedConfig.defaultItems)) {
|
||||
const nvalue = resolvedConfig.defaultItems?.map((label) => {
|
||||
return typeof label === 'string' ? label : `NOT_STRING`
|
||||
})
|
||||
value = [...new Set(nvalue)]
|
||||
outputs?.result.set([...(value ?? [])])
|
||||
}
|
||||
}
|
||||
const outputs = initOutput($worldStore, id, { result: [] as any[] })
|
||||
let options: ObjectOption[] = []
|
||||
let selectedOptions: ObjectOption[] = [...new Set(findOptionsByValue(outputs?.result.peak()))]
|
||||
|
||||
let css = initCss($app.css?.multiselectcomponent, customCss)
|
||||
let outerDiv: HTMLDivElement | undefined = undefined
|
||||
let portalRef: HTMLDivElement | undefined = undefined
|
||||
let w = 0
|
||||
let open: boolean = false
|
||||
|
||||
function setOuterDivStyle(outerDiv: HTMLDivElement, portalRef: HTMLDivElement, style: string) {
|
||||
outerDiv.setAttribute('style', style)
|
||||
// find ul in portalRef and set style
|
||||
const ul = portalRef.querySelector('ul')
|
||||
ul?.setAttribute('style', extractCustomProperties(style))
|
||||
$: if (resolvedConfig.items) {
|
||||
options = parseConfigOptions(resolvedConfig.items)
|
||||
}
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(newValues: any[]) {
|
||||
selectOptionsByValue(newValues)
|
||||
}
|
||||
}
|
||||
|
||||
$: if (resolvedConfig.defaultItems) {
|
||||
selectOptionsByValue(resolvedConfig.defaultItems)
|
||||
}
|
||||
|
||||
$: outerDiv &&
|
||||
@@ -86,8 +67,56 @@
|
||||
css?.multiselect?.style &&
|
||||
setOuterDivStyle(outerDiv, portalRef, css?.multiselect?.style)
|
||||
|
||||
let outerDiv: HTMLDivElement | undefined = undefined
|
||||
let portalRef: HTMLDivElement | undefined = undefined
|
||||
$: if (render && portalRef && outerDiv && options?.length > 0) {
|
||||
tick().then(() => {
|
||||
moveOptionsToPortal()
|
||||
})
|
||||
}
|
||||
|
||||
function findOptionsByValue(values: any[]) {
|
||||
if (!Array.isArray(values)) {
|
||||
return []
|
||||
}
|
||||
return options?.filter((item) => {
|
||||
let itemValue = item.value
|
||||
try {
|
||||
if (typeof itemValue == 'string') {
|
||||
itemValue = JSON.parse(itemValue)
|
||||
}
|
||||
} catch (_) {}
|
||||
return values.some((value) => deepEqual(itemValue, value))
|
||||
}) as ObjectOption[]
|
||||
}
|
||||
|
||||
function selectOptionsByValue(values: any[]) {
|
||||
if (!Array.isArray(values)) {
|
||||
outputs?.result.set([])
|
||||
}
|
||||
|
||||
selectedOptions = findOptionsByValue(values)
|
||||
outputs?.result.set([...toValues(selectedOptions)])
|
||||
}
|
||||
|
||||
function toValues(options: ObjectOption[] | undefined) {
|
||||
if (!options || !Array.isArray(options)) {
|
||||
return []
|
||||
}
|
||||
|
||||
return options.map((o) => {
|
||||
let val = o.value
|
||||
try {
|
||||
if (typeof val === 'string') val = JSON.parse(val)
|
||||
} catch (_) {}
|
||||
return val
|
||||
})
|
||||
}
|
||||
|
||||
function setOuterDivStyle(outerDiv: HTMLDivElement, portalRef: HTMLDivElement, style: string) {
|
||||
outerDiv.setAttribute('style', style)
|
||||
// find ul in portalRef and set style
|
||||
const ul = portalRef.querySelector('ul')
|
||||
ul?.setAttribute('style', extractCustomProperties(style))
|
||||
}
|
||||
|
||||
function moveOptionsToPortal() {
|
||||
// Find ul element with class 'options' within the outerDiv
|
||||
@@ -98,14 +127,6 @@
|
||||
portalRef?.appendChild(ul)
|
||||
}
|
||||
}
|
||||
|
||||
$: if (render && portalRef && outerDiv && items?.length > 0) {
|
||||
tick().then(() => {
|
||||
moveOptionsToPortal()
|
||||
})
|
||||
}
|
||||
let w = 0
|
||||
let open: boolean = false
|
||||
</script>
|
||||
|
||||
{#each Object.keys(components['multiselectcomponent'].initialData.configuration) as key (key)}
|
||||
@@ -128,7 +149,6 @@
|
||||
{/each}
|
||||
|
||||
<InitializeComponent {id} />
|
||||
|
||||
<AlignWrapper {render} hFull {verticalAlignment}>
|
||||
<div
|
||||
class="w-full app-editor-input"
|
||||
@@ -143,7 +163,7 @@
|
||||
use:floatingRef
|
||||
bind:clientWidth={w}
|
||||
>
|
||||
{#if !value || Array.isArray(value)}
|
||||
{#if !selectedOptions || Array.isArray(selectedOptions)}
|
||||
<MultiSelect
|
||||
bind:outerDiv
|
||||
outerDivClass={`${resolvedConfig.allowOverflow ? '' : 'h-full'}`}
|
||||
@@ -151,15 +171,19 @@
|
||||
--sms-border={'none'}
|
||||
--sms-min-height={'32px'}
|
||||
--sms-focus-border={'none'}
|
||||
bind:selected={value}
|
||||
options={items}
|
||||
bind:selected={selectedOptions}
|
||||
{options}
|
||||
placeholder={resolvedConfig.placeholder}
|
||||
allowUserOptions={resolvedConfig.create}
|
||||
key={(option) => {
|
||||
if (typeof option == 'string' || typeof option == 'number') return option
|
||||
return option.value
|
||||
}}
|
||||
on:change={(event) => {
|
||||
if (event?.detail?.type === 'removeAll') {
|
||||
outputs?.result.set([])
|
||||
} else {
|
||||
outputs?.result.set([...(value ?? [])])
|
||||
outputs?.result.set([...toValues(selectedOptions)])
|
||||
}
|
||||
}}
|
||||
on:open={() => {
|
||||
@@ -181,9 +205,10 @@
|
||||
e.target?.['parentElement']?.dispatchEvent(newe)
|
||||
}}
|
||||
>
|
||||
{option}
|
||||
{@html option.label === '' ? ` ` : option.label}
|
||||
</div>
|
||||
</MultiSelect>
|
||||
|
||||
<Portal name="app-multiselect-v2">
|
||||
<div use:floatingContent class="z5000" hidden={!open}>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
@@ -197,7 +222,7 @@
|
||||
</div>
|
||||
</Portal>
|
||||
{:else}
|
||||
Value {value} is not an array
|
||||
Value {selectedOptions} is not an array
|
||||
{/if}
|
||||
</div>
|
||||
</AlignWrapper>
|
||||
|
||||
48
frontend/src/lib/components/apps/components/inputs/utils.ts
Normal file
48
frontend/src/lib/components/apps/components/inputs/utils.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import {
|
||||
type ObjectOption,
|
||||
isObjectOptionArray,
|
||||
isStringArray
|
||||
} from '$lib/components/multiselect/types'
|
||||
import type { StaticAppInput } from '../../inputType'
|
||||
|
||||
export function parseConfigOptions(resolvedConfigItems: StaticAppInput) {
|
||||
if (!resolvedConfigItems) {
|
||||
return []
|
||||
}
|
||||
if (isObjectOptionArray(resolvedConfigItems)) {
|
||||
return parseLabeledItems(resolvedConfigItems)
|
||||
} else if (isStringArray(resolvedConfigItems)) {
|
||||
return parseStringItems(resolvedConfigItems)
|
||||
}
|
||||
return []
|
||||
}
|
||||
export function parseLabeledItems(resolvedConfigItems: ObjectOption[]) {
|
||||
return resolvedConfigItems?.map((item: ObjectOption) => {
|
||||
if (!item || typeof item !== 'object') {
|
||||
console.error(
|
||||
'When labeled, MultiSelect component items should be an array of { label: string, value: string }.'
|
||||
)
|
||||
return {
|
||||
label: 'not object',
|
||||
value: 'not object'
|
||||
}
|
||||
}
|
||||
return {
|
||||
label: item?.label ?? 'undefined',
|
||||
value:
|
||||
typeof item?.value === 'object' ? JSON.stringify(item.value) : item?.value ?? 'undefined'
|
||||
}
|
||||
})
|
||||
}
|
||||
export function parseStringItems(resolvedConfigItems: string[]): ObjectOption[] {
|
||||
return resolvedConfigItems?.map((option: string) => {
|
||||
if (option === null || option === undefined || typeof option !== 'string') {
|
||||
console.error('When not labeled, MultiSelect component items should be an array of strings.')
|
||||
return { label: 'not string', value: 'not string' }
|
||||
}
|
||||
if (option === '') {
|
||||
return { label: 'empty string', value: 'empty string' }
|
||||
}
|
||||
return { label: option, value: option }
|
||||
})
|
||||
}
|
||||
@@ -41,7 +41,8 @@
|
||||
copyToClipboard,
|
||||
truncateRev,
|
||||
orderedJsonStringify,
|
||||
type Value
|
||||
type Value,
|
||||
replaceFalseWithUndefined
|
||||
} from '../../../utils'
|
||||
import type {
|
||||
AppInput,
|
||||
@@ -422,13 +423,27 @@
|
||||
// We need it to show diff
|
||||
// Handle through confirmation modal
|
||||
await syncWithDeployed()
|
||||
|
||||
confirmCallback = async () => {
|
||||
open = false
|
||||
if (
|
||||
deployedValue &&
|
||||
savedApp &&
|
||||
$app &&
|
||||
orderedJsonStringify(deployedValue) ===
|
||||
orderedJsonStringify(replaceFalseWithUndefined({
|
||||
summary: $summary,
|
||||
value: $app,
|
||||
path: newPath || savedApp.draft?.path || savedApp.path,
|
||||
policy
|
||||
}))
|
||||
) {
|
||||
await updateApp(npath)
|
||||
} else {
|
||||
confirmCallback = async () => {
|
||||
open = false
|
||||
await updateApp(npath)
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
// Open confirmation modal
|
||||
open = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,15 +457,14 @@
|
||||
deployedBy = deployedApp.created_by
|
||||
|
||||
// Strip off extra information
|
||||
deployedValue = {
|
||||
deployedValue = replaceFalseWithUndefined({
|
||||
...deployedApp,
|
||||
starred: undefined,
|
||||
id: undefined,
|
||||
created_at: undefined,
|
||||
created_by: undefined,
|
||||
versions: undefined,
|
||||
extra_perms: undefined //
|
||||
}
|
||||
extra_perms: undefined
|
||||
})
|
||||
}
|
||||
|
||||
async function updateApp(npath: string) {
|
||||
|
||||
@@ -2079,7 +2079,8 @@ This is a paragraph.
|
||||
value: [
|
||||
{ value: 'foo', label: 'Foo' },
|
||||
{ value: 'bar', label: 'Bar' }
|
||||
]
|
||||
],
|
||||
hasLabeledMode: true
|
||||
} as StaticAppInput,
|
||||
create: {
|
||||
type: 'static',
|
||||
@@ -2199,14 +2200,15 @@ This is a paragraph.
|
||||
items: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'text',
|
||||
value: ['Foo', 'Bar']
|
||||
subFieldType: 'simplestringselect',
|
||||
value: ['Foo', 'Bar'],
|
||||
hasLabeledMode: true
|
||||
} as StaticAppInput,
|
||||
defaultItems: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'text',
|
||||
value: []
|
||||
subFieldType: 'simplestringselect',
|
||||
value: undefined
|
||||
} as StaticAppInput,
|
||||
placeholder: {
|
||||
type: 'static',
|
||||
|
||||
@@ -9,15 +9,30 @@
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import QuickAddColumn from './QuickAddColumn.svelte'
|
||||
import RefreshDatabaseStudioTable from './RefreshDatabaseStudioTable.svelte'
|
||||
import { isObjectOptionArray, isStringArray } from '$lib/components/multiselect/types'
|
||||
|
||||
export let componentInput: StaticInput<any[]> & { loading?: boolean }
|
||||
export let componentInput: StaticInput<any[]> & {
|
||||
loading?: boolean
|
||||
expr?: string
|
||||
isLabeled?: boolean
|
||||
}
|
||||
export let subFieldType: InputType | undefined = undefined
|
||||
export let selectOptions: StaticOptions['selectOptions'] | undefined = undefined
|
||||
export let id: string | undefined
|
||||
export let hasLabeledMode: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const flipDurationMs = 200
|
||||
|
||||
let items = getItems(componentInput)
|
||||
let raw: boolean = false
|
||||
let labeled: boolean = subFieldType === 'labeledselect'
|
||||
|
||||
$: subFieldType === 'db-explorer' && clearTableOnComponentReset(componentInput?.value)
|
||||
|
||||
$: labeled !== undefined && handleLabeledChange()
|
||||
$: items !== undefined && handleItemsChange()
|
||||
|
||||
function addElementByType() {
|
||||
if (!Array.isArray(componentInput.value)) {
|
||||
componentInput.value = []
|
||||
@@ -32,12 +47,13 @@
|
||||
} else if (subFieldType === 'object') {
|
||||
value.push({})
|
||||
} else if (subFieldType === 'labeledresource' || subFieldType === 'labeledselect') {
|
||||
value.push({ value: 'value', label: 'label' })
|
||||
value.push({ label: 'label', value: 'value' })
|
||||
} else if (subFieldType === 'tab-select') {
|
||||
value.push({ id: '', index: 0 })
|
||||
} else if (
|
||||
subFieldType === 'text' ||
|
||||
subFieldType === 'textarea' ||
|
||||
subFieldType === 'simplestringselect' ||
|
||||
// TODO: Add support for these types
|
||||
subFieldType === 'date' ||
|
||||
subFieldType === 'time' ||
|
||||
@@ -193,8 +209,6 @@
|
||||
componentInput.value = reorderedValues
|
||||
}
|
||||
|
||||
let items = getItems(componentInput)
|
||||
|
||||
function getItems(componentInput: StaticInput<any[]> & { loading?: boolean }) {
|
||||
return (Array.isArray(componentInput.value) ? componentInput.value : [])
|
||||
.filter((x) => x != undefined)
|
||||
@@ -209,15 +223,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: subFieldType === 'db-explorer' && clearTableOnComponentReset(componentInput?.value)
|
||||
|
||||
$: items != undefined && handleItemsChange()
|
||||
|
||||
function handleItemsChange() {
|
||||
componentInput.value = items.map((item) => item.value).filter((item) => item != undefined)
|
||||
const newComponentInput = { ...componentInput }
|
||||
newComponentInput.value = items.map((item) => item.value).filter((item) => item != undefined)
|
||||
newComponentInput.expr = JSON.stringify(newComponentInput.value)
|
||||
newComponentInput.isLabeled = labeled
|
||||
|
||||
dispatch('componentInputChange', newComponentInput)
|
||||
}
|
||||
|
||||
/** Transforms items string[] to ObjectOption] and vice versa. Mutating items will fire handleItemsChange. */
|
||||
function handleLabeledChange() {
|
||||
if (labeled && isStringArray(items.map((item) => item.value))) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const itemValue = items[i].value
|
||||
items[i].value = { label: itemValue, value: itemValue }
|
||||
}
|
||||
} else if (!labeled && isObjectOptionArray(items.map((item) => item.value))) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const itemValue = items[i].value
|
||||
items[i].value = itemValue.label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let raw: boolean = false
|
||||
// let mounted = false
|
||||
|
||||
// $: if (componentInput.value && mounted) {
|
||||
@@ -243,7 +272,6 @@
|
||||
{#if Array.isArray(items) && componentInput.value}
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<div class="text-xs text-tertiary font-semibold">{pluralize(items.length, 'item')}</div>
|
||||
|
||||
{#if subFieldType === 'ag-grid' || subFieldType === 'table-column'}
|
||||
<Toggle
|
||||
options={{
|
||||
@@ -253,6 +281,16 @@
|
||||
bind:checked={raw}
|
||||
/>
|
||||
{/if}
|
||||
{#if hasLabeledMode}
|
||||
<Toggle
|
||||
options={{
|
||||
right: 'w/ label'
|
||||
}}
|
||||
size="xs"
|
||||
bind:checked={labeled}
|
||||
on:change={handleLabeledChange}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<section
|
||||
use:dragHandleZone={{
|
||||
@@ -271,7 +309,7 @@
|
||||
<div class="grow min-w-0">
|
||||
<SubTypeEditor
|
||||
{id}
|
||||
subFieldType={raw ? 'object' : subFieldType}
|
||||
subFieldType={raw ? 'object' : labeled ? 'labeledselect' : subFieldType}
|
||||
bind:componentInput
|
||||
bind:value={item.value}
|
||||
on:remove={() => deleteElementByType(index)}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
export let documentationLink: string | undefined = undefined
|
||||
export let markdownTooltip: string | undefined = undefined
|
||||
export let securedContext = false
|
||||
export let hasLabeledMode = false
|
||||
|
||||
const { connectingInput, app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
@@ -171,6 +172,7 @@
|
||||
{selectOptions}
|
||||
{format}
|
||||
{placeholder}
|
||||
{hasLabeledMode}
|
||||
bind:componentInput
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
{recomputeOnInputChanged}
|
||||
{showOnDemandOnlyToggle}
|
||||
{securedContext}
|
||||
hasLabeledMode={meta?.['hasLabeledMode']}
|
||||
/>
|
||||
{#if deletable}
|
||||
<div class="flex flex-row-reverse -mt-4">
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
editor?.setCode(code)
|
||||
}
|
||||
|
||||
let fullscreen = false
|
||||
let focus = false
|
||||
|
||||
$: extraLib =
|
||||
componentInput?.expr && $worldStore
|
||||
? buildExtraLib($worldStore?.outputsById ?? {}, acceptSelf ? '' : id, $state, false)
|
||||
@@ -52,9 +55,6 @@
|
||||
inferDeps(code, $worldStore.outputsById, componentInput, app)
|
||||
}
|
||||
}
|
||||
|
||||
let fullscreen = false
|
||||
let focus = false
|
||||
</script>
|
||||
|
||||
{#if componentInput?.type === 'evalv2'}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import ArrayStaticInputEditor from '../ArrayStaticInputEditor.svelte'
|
||||
import ResourcePicker from '$lib/components/ResourcePicker.svelte'
|
||||
import JsonEditor from './JsonEditor.svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import type { AppViewerContext } from '$lib/components/apps/types'
|
||||
import IconSelectInput from './IconSelectInput.svelte'
|
||||
import ColorInput from './ColorInput.svelte'
|
||||
@@ -24,17 +24,49 @@
|
||||
import EditableSchemaDrawer from '$lib/components/schema/EditableSchemaDrawer.svelte'
|
||||
import AppPicker from '$lib/components/wizards/AppPicker.svelte'
|
||||
|
||||
export let componentInput: StaticInput<any> | undefined
|
||||
export let componentInput: (StaticInput<any> & { isLabeled?: boolean }) | undefined
|
||||
export let fieldType: InputType | undefined = undefined
|
||||
export let subFieldType: InputType | undefined = undefined
|
||||
export let selectOptions: StaticOptions['selectOptions'] | undefined = undefined
|
||||
export let placeholder: string | undefined = undefined
|
||||
export let format: string | undefined = undefined
|
||||
export let id: string | undefined
|
||||
export let hasLabeledMode: boolean = false
|
||||
|
||||
const { onchange } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
$: componentInput && onchange?.()
|
||||
|
||||
onMount(() => {
|
||||
/** preserve the `labeled` toggling when switching from eval to static */
|
||||
if (componentInput !== undefined) {
|
||||
handleComponentInputChange(componentInput)
|
||||
}
|
||||
})
|
||||
/**
|
||||
* Every components: switching from `static` to `eval` preserves the user data
|
||||
*
|
||||
* Multiselect: toggling `labeled` needs to mutate input value and input fieldType.
|
||||
* */
|
||||
function handleComponentInputChange(newComponentInput: StaticInput<any>) {
|
||||
componentInput = { ...componentInput, ...newComponentInput }
|
||||
|
||||
if (componentInput?.isLabeled) {
|
||||
if (fieldType === 'array' && subFieldType === 'simplestringselect') {
|
||||
subFieldType = 'labeledselect'
|
||||
}
|
||||
if (fieldType === 'simplestringselect') {
|
||||
fieldType = 'labeledselect'
|
||||
}
|
||||
} else if (componentInput?.isLabeled === false) {
|
||||
if (fieldType === 'array' && subFieldType === 'labeledselect') {
|
||||
subFieldType = 'simplestringselect'
|
||||
}
|
||||
if (fieldType === 'labeledselect') {
|
||||
fieldType = 'simplestringselect'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#key subFieldType}
|
||||
@@ -133,7 +165,7 @@
|
||||
{/if}
|
||||
{:else if fieldType === 'color'}
|
||||
<ColorInput bind:value={componentInput.value} />
|
||||
{:else if fieldType === 'object' || fieldType == 'labeledselect'}
|
||||
{:else if fieldType === 'object' || fieldType == 'labeledselect' || fieldType === 'simplestringselect'}
|
||||
{#if format?.startsWith('resource-') && (componentInput.value == undefined || typeof componentInput.value == 'string')}
|
||||
<ResourcePicker
|
||||
initialValue={componentInput.value?.split('$res:')?.[1] || ''}
|
||||
@@ -162,7 +194,14 @@
|
||||
</div>
|
||||
{/if}
|
||||
{:else if fieldType === 'array'}
|
||||
<ArrayStaticInputEditor {id} {subFieldType} bind:componentInput on:deleteArrayItem />
|
||||
<ArrayStaticInputEditor
|
||||
{id}
|
||||
{subFieldType}
|
||||
bind:componentInput
|
||||
on:deleteArrayItem
|
||||
on:componentInputChange={(e) => handleComponentInputChange(e.detail)}
|
||||
{hasLabeledMode}
|
||||
/>
|
||||
{:else if fieldType === 'schema'}
|
||||
<div class="w-full">
|
||||
<EditableSchemaDrawer bind:schema={componentInput.value} />
|
||||
|
||||
@@ -20,6 +20,7 @@ export type InputType =
|
||||
| 'any'
|
||||
| 'labeledresource'
|
||||
| 'labeledselect'
|
||||
| 'simplestringselect'
|
||||
| 'tab-select'
|
||||
| 'schema'
|
||||
| 'ag-grid'
|
||||
@@ -175,6 +176,7 @@ type InputConfiguration<T extends InputType, V extends InputType> = {
|
||||
noStatic?: boolean
|
||||
onDemandOnly?: boolean
|
||||
hideRefreshButton?: boolean
|
||||
isLabeled?: boolean
|
||||
}
|
||||
|
||||
export type StaticOptions = {
|
||||
@@ -207,6 +209,7 @@ export type AppInput =
|
||||
| (AppInputSpec<'array', string[], 'select'> & StaticOptions)
|
||||
| AppInputSpec<'array', object[], 'labeledresource'>
|
||||
| AppInputSpec<'array', object[], 'labeledselect'>
|
||||
| AppInputSpec<'array', string[], 'simplestringselect'>
|
||||
| AppInputSpec<'labeledselect', object>
|
||||
| AppInputSpec<'labeledresource', object>
|
||||
| AppInputSpec<'array', object[], 'tab-select'>
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
import { goto as gotoUrl } from '$app/navigation'
|
||||
import Button from '../button/Button.svelte'
|
||||
import type DiffDrawer from '$lib/components/DiffDrawer.svelte'
|
||||
import { cleanValueProperties, orderedJsonStringify, type Value } from '$lib/utils'
|
||||
import {
|
||||
cleanValueProperties,
|
||||
orderedJsonStringify,
|
||||
replaceFalseWithUndefined,
|
||||
type Value
|
||||
} from '$lib/utils'
|
||||
import { tick } from 'svelte'
|
||||
import { page } from '$app/stores'
|
||||
|
||||
@@ -36,7 +41,10 @@
|
||||
path: undefined
|
||||
})
|
||||
const current = cleanValueProperties({ ...(modifiedValue ?? {}), path: undefined })
|
||||
if (orderedJsonStringify(draftOrDeployed) === orderedJsonStringify(current)) {
|
||||
if (
|
||||
orderedJsonStringify(replaceFalseWithUndefined(draftOrDeployed)) ===
|
||||
orderedJsonStringify(replaceFalseWithUndefined(current))
|
||||
) {
|
||||
bypassBeforeNavigate = true
|
||||
gotoUrl(goingTo)
|
||||
} else {
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{:else if $selectedId === 'Input'}
|
||||
<FlowInput {noEditor} disabled={disabledFlowInputs} />
|
||||
{:else if $selectedId === 'Result'}
|
||||
<p class="p-4 text-secondary">Nothing to show about the result node. Happy flow building!</p>
|
||||
<p class="p-4 text-secondary">The result of the flow will be the result of the last node.</p>
|
||||
{:else if $selectedId === 'constants'}
|
||||
<FlowConstants {noEditor} />
|
||||
{:else if $selectedId === 'failure'}
|
||||
|
||||
@@ -45,3 +45,30 @@ export type MultiSelectEvents = {
|
||||
touchmove: TouchEvent
|
||||
touchstart: TouchEvent
|
||||
}
|
||||
|
||||
export function isObjectOption(item: any): item is ObjectOption {
|
||||
if (!item || item !== Object(item)) {
|
||||
return false
|
||||
}
|
||||
if (item.label === undefined || item.label === null) {
|
||||
return false
|
||||
}
|
||||
if (typeof item.label !== 'string' && typeof item.label !== 'number') {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function isObjectOptionArray(arr: any): arr is ObjectOption[] {
|
||||
if (!arr || !Array.isArray(arr)) {
|
||||
return false
|
||||
}
|
||||
return arr.every((item) => isObjectOption(item))
|
||||
}
|
||||
|
||||
export function isStringArray(arr: any): arr is string[] {
|
||||
if (!arr || !Array.isArray(arr)) {
|
||||
return false
|
||||
}
|
||||
return arr.every((item) => typeof item === 'string')
|
||||
}
|
||||
|
||||
@@ -799,6 +799,30 @@ export type Value = {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export function replaceFalseWithUndefined(obj: any) {
|
||||
return replaceFalseWithUndefinedRec(structuredClone(obj))
|
||||
}
|
||||
|
||||
function replaceFalseWithUndefinedRec(obj: any) {
|
||||
// Check if the input is an object and not null
|
||||
if (obj !== null && typeof obj === 'object') {
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
// If the value is false, replace it with undefined
|
||||
if (obj[key] === false) {
|
||||
// delete obj[key];
|
||||
obj[key] = undefined;
|
||||
|
||||
} else {
|
||||
// If the value is an object, call the function recursively
|
||||
replaceFalseWithUndefinedRec(obj[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
export function cleanValueProperties(obj: Value) {
|
||||
if (typeof obj !== 'object') {
|
||||
return obj
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
...structuredClone(flowWithDraft.draft),
|
||||
path: flowWithDraft.draft.path ?? flowWithDraft.path // backward compatibility for old drafts missing path
|
||||
}
|
||||
: undefined
|
||||
: undefined
|
||||
} as Flow & {
|
||||
draft?: Flow
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.424.0"
|
||||
wmill_pg = ">=1.424.0"
|
||||
wmill = ">=1.425.1"
|
||||
wmill_pg = ">=1.425.1"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.424.0
|
||||
version: 1.425.1
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'WindmillClient.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.424.0'
|
||||
ModuleVersion = '1.425.1'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
description = "A client library for accessing Windmill server wrapping the Windmill client API"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill-pg"
|
||||
version = "1.424.0"
|
||||
version = "1.425.1"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@windmill/windmill",
|
||||
"version": "1.424.0",
|
||||
"version": "1.425.1",
|
||||
"exports": "./src/index.ts",
|
||||
"publish": {
|
||||
"exclude": ["!src", "./s3Types.ts", "./client.ts"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "windmill-client",
|
||||
"description": "Windmill SDK client for browsers and Node.js",
|
||||
"version": "1.424.0",
|
||||
"version": "1.425.1",
|
||||
"author": "Ruben Fiszel",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.424.0
|
||||
1.425.1
|
||||
|
||||
Reference in New Issue
Block a user