Compare commits

...

7 Commits

Author SHA1 Message Date
Ruben Fiszel
0ca4ec9d32 all 2023-12-12 18:13:48 +01:00
Ruben Fiszel
88149c6d93 autoset base_url if empty 2023-12-11 00:27:59 +01:00
Ruben Fiszel
f43e31b967 make currency input more resilient 2023-12-10 21:21:50 +01:00
Ruben Fiszel
cc805a06b5 chore(main): release 1.224.0 (#2825)
* chore(main): release 1.224.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
2023-12-10 13:53:39 +01:00
Ruben Fiszel
58c4c0b5c2 fix: make cleanup_module backcompatible 2023-12-10 13:29:51 +01:00
Ruben Fiszel
4f4ca264ae feat: embedded server only get killed after last job of worker 2023-12-10 10:51:32 +01:00
Amir Zarrinkafsh
6fefdb5438 feat: add authelia sso support (#2824)
This change adds the ability to integrate Windmill with Authelia via OIDC.
2023-12-09 14:50:29 +01:00
27 changed files with 325 additions and 143 deletions

View File

@@ -1,6 +1,19 @@
# Changelog
## [1.224.0](https://github.com/windmill-labs/windmill/compare/v1.223.1...v1.224.0) (2023-12-10)
### Features
* add authelia sso support ([#2824](https://github.com/windmill-labs/windmill/issues/2824)) ([6fefdb5](https://github.com/windmill-labs/windmill/commit/6fefdb5438d0fd7546759d93b5f4465731a4cac5))
* embedded server only get killed after last job of worker ([4f4ca26](https://github.com/windmill-labs/windmill/commit/4f4ca264aef3e1d3ee4748593f0ebcb425d333ef))
### Bug Fixes
* make cleanup_module backcompatible ([58c4c0b](https://github.com/windmill-labs/windmill/commit/58c4c0b5c2b009ff56e3eb6bd19e766dbff4cf54))
## [1.223.1](https://github.com/windmill-labs/windmill/compare/v1.223.0...v1.223.1) (2023-12-08)

100
backend/Cargo.lock generated
View File

@@ -365,7 +365,7 @@ dependencies = [
"futures-lite 2.1.0",
"parking",
"polling 3.3.1",
"rustix 0.38.27",
"rustix 0.38.28",
"slab",
"tracing",
"windows-sys 0.52.0",
@@ -598,7 +598,7 @@ dependencies = [
"aws-sdk-ssooidc",
"aws-sdk-sts",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-json",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
@@ -655,7 +655,7 @@ dependencies = [
"aws-sigv4",
"aws-smithy-async",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-runtime-api",
"aws-smithy-types",
"aws-types",
@@ -679,7 +679,7 @@ dependencies = [
"aws-smithy-async",
"aws-smithy-checksums",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-json",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
@@ -706,7 +706,7 @@ dependencies = [
"aws-http",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-json",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
@@ -728,7 +728,7 @@ dependencies = [
"aws-http",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-json",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
@@ -750,7 +750,7 @@ dependencies = [
"aws-http",
"aws-runtime",
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-json",
"aws-smithy-query",
"aws-smithy-runtime",
@@ -771,7 +771,7 @@ checksum = "b6bcbad6e0f130232b22e4b4e28834348ce5b79c23b5059b387c08fd0dc8f876"
dependencies = [
"aws-credential-types",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
@@ -809,7 +809,7 @@ version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5a373ec01aede3dd066ec018c1bc4e8f5dd11b2c11c59c8eef1a5c68101f397"
dependencies = [
"aws-smithy-http",
"aws-smithy-http 0.60.0",
"aws-smithy-types",
"bytes",
"crc32c",
@@ -856,6 +856,26 @@ dependencies = [
"tracing",
]
[[package]]
name = "aws-smithy-http"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e68d7a4a9b8be1342066dd8b26c925e79f4e399a7e57ee22f9d162eb041d592"
dependencies = [
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
"bytes-utils",
"futures-core",
"http",
"http-body",
"once_cell",
"percent-encoding",
"pin-project-lite",
"pin-utils",
"tracing",
]
[[package]]
name = "aws-smithy-json"
version = "0.60.0"
@@ -877,12 +897,12 @@ dependencies = [
[[package]]
name = "aws-smithy-runtime"
version = "1.0.3"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0c628feae802ab1589936e2aaef6f8ab2b8fc1ee1f947c276dd8a7c3cda1904"
checksum = "0de8c54dd9c5a159013f1e6885cb7c1ae8fc98dc286d2aebe71737effef28e37"
dependencies = [
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http 0.61.0",
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
@@ -3772,9 +3792,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "itoap"
@@ -5491,7 +5511,7 @@ dependencies = [
"cfg-if",
"concurrent-queue",
"pin-project-lite",
"rustix 0.38.27",
"rustix 0.38.28",
"tracing",
"windows-sys 0.52.0",
]
@@ -6426,9 +6446,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.27"
version = "0.38.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfeae074e687625746172d639330f1de242a178bf3189b51e35a7a21573513ac"
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
dependencies = [
"bitflags 2.4.1",
"errno",
@@ -6588,9 +6608,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.15"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "safetensors"
@@ -8166,7 +8186,7 @@ dependencies = [
"cfg-if",
"fastrand 2.0.1",
"redox_syscall 0.4.1",
"rustix 0.38.27",
"rustix 0.38.28",
"windows-sys 0.48.0",
]
@@ -9366,7 +9386,7 @@ dependencies = [
"either",
"home",
"once_cell",
"rustix 0.38.27",
"rustix 0.38.28",
]
[[package]]
@@ -9412,7 +9432,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windmill"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"axum",
@@ -9447,7 +9467,7 @@ dependencies = [
[[package]]
name = "windmill-api"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"argon2",
@@ -9519,7 +9539,7 @@ dependencies = [
[[package]]
name = "windmill-api-client"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"base64 0.21.5",
"chrono",
@@ -9537,7 +9557,7 @@ dependencies = [
[[package]]
name = "windmill-audit"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"chrono",
"serde",
@@ -9550,7 +9570,7 @@ dependencies = [
[[package]]
name = "windmill-common"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"axum",
@@ -9581,7 +9601,7 @@ dependencies = [
[[package]]
name = "windmill-parser"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"serde",
"serde_json",
@@ -9589,7 +9609,7 @@ dependencies = [
[[package]]
name = "windmill-parser-bash"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -9600,7 +9620,7 @@ dependencies = [
[[package]]
name = "windmill-parser-go"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"gosyn",
@@ -9612,7 +9632,7 @@ dependencies = [
[[package]]
name = "windmill-parser-graphql"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -9623,7 +9643,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"itertools 0.12.0",
@@ -9634,7 +9654,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py-imports"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"async-recursion",
@@ -9651,7 +9671,7 @@ dependencies = [
[[package]]
name = "windmill-parser-sql"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -9662,7 +9682,7 @@ dependencies = [
[[package]]
name = "windmill-parser-ts"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@@ -9679,7 +9699,7 @@ dependencies = [
[[package]]
name = "windmill-parser-wasm"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"getrandom 0.2.11",
@@ -9697,7 +9717,7 @@ dependencies = [
[[package]]
name = "windmill-queue"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"async-recursion",
@@ -9729,7 +9749,7 @@ dependencies = [
[[package]]
name = "windmill-worker"
version = "1.223.1"
version = "1.224.0"
dependencies = [
"anyhow",
"async-recursion",
@@ -10027,11 +10047,13 @@ dependencies = [
[[package]]
name = "xattr"
version = "1.0.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985"
checksum = "d367426ae76bdfce3d8eaea6e94422afd6def7d46f9c89e2980309115b3c2c41"
dependencies = [
"libc",
"linux-raw-sys 0.4.12",
"rustix 0.38.28",
]
[[package]]

View File

@@ -1,6 +1,6 @@
[package]
name = "windmill"
version = "1.223.1"
version = "1.224.0"
authors.workspace = true
edition.workspace = true
@@ -21,7 +21,7 @@ members = [
]
[workspace.package]
version = "1.223.1"
version = "1.224.0"
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
edition = "2021"

View File

@@ -218,7 +218,7 @@ async fn main() -> anyhow::Result<()> {
// migration code to avoid break
windmill_api::migrate_db(&db).await?;
let last_mig_version = sqlx::query_scalar!(
let new_last_mig_version = sqlx::query_scalar!(
"select version from _sqlx_migrations order by version desc limit 1;"
)
.fetch_optional(&db)
@@ -226,12 +226,19 @@ async fn main() -> anyhow::Result<()> {
.ok()
.flatten();
tracing::info!(
"Completed potential migration of the db. Last migration version: {last_mig_version:?}",
);
if last_mig_version != new_last_mig_version {
tracing::info!(
"Completed migration of the db. New migration version: {}",
new_last_mig_version.unwrap_or(-1)
);
} else {
tracing::info!("No migration, db was up-to-date");
}
}
let (tx, rx) = tokio::sync::broadcast::channel::<()>(3);
let shutdown_signal = windmill_common::shutdown_signal(tx.clone(), rx.resubscribe());
let (killpill_tx, killpill_rx) = tokio::sync::broadcast::channel::<()>(2);
let (killpill_phase2_tx, killpill_phase2_rx) = tokio::sync::broadcast::channel::<()>(2);
let shutdown_signal =
windmill_common::shutdown_signal(killpill_tx.clone(), killpill_rx.resubscribe());
#[cfg(feature = "enterprise")]
tracing::info!(
@@ -275,7 +282,7 @@ Windmill Community Edition {GIT_VERSION}
default_base_internal_url.clone()
};
initial_load(&db, tx.clone(), worker_mode, server_mode).await;
initial_load(&db, killpill_tx.clone(), worker_mode, server_mode).await;
monitor_db(&db, &base_internal_url, rsmq.clone(), server_mode).await;
@@ -298,7 +305,7 @@ Windmill Community Edition {GIT_VERSION}
db.clone(),
rsmq2,
addr,
rx.resubscribe(),
killpill_phase2_rx.resubscribe(),
base_internal_tx,
server_mode,
)
@@ -318,25 +325,29 @@ Windmill Community Edition {GIT_VERSION}
if worker_mode {
run_workers(
db.clone(),
rx.resubscribe(),
tx.clone(),
killpill_rx.resubscribe(),
killpill_tx.clone(),
num_workers,
base_internal_url.clone(),
rsmq.clone(),
)
.await?;
tracing::info!("All workers exited.");
tx.send(())?; // signal server to shutdown
killpill_tx.send(())?;
} else {
killpill_rx.resubscribe().recv().await?;
}
tracing::info!("Starting phase 2 of shutdown");
killpill_phase2_tx.send(())?;
Ok(()) as anyhow::Result<()>
};
let monitor_f = async {
let db = db.clone();
let tx = tx.clone();
let tx = killpill_tx.clone();
let rsmq = rsmq.clone();
let mut rx = rx.resubscribe();
let mut rx = killpill_rx.resubscribe();
let base_internal_url = base_internal_url.to_string();
let h = tokio::spawn(async move {
let mut listener = retry_listen_pg(&db).await;
@@ -472,8 +483,12 @@ Windmill Community Edition {GIT_VERSION}
tracing::error!("Metrics are only available in the EE, ignoring...");
#[cfg(feature = "enterprise")]
windmill_common::serve_metrics(*METRICS_ADDR, rx.resubscribe(), num_workers > 0)
.await;
windmill_common::serve_metrics(
*METRICS_ADDR,
killpill_phase2_rx.resubscribe(),
num_workers > 0,
)
.await;
}
Ok(()) as anyhow::Result<()>
};
@@ -481,7 +496,7 @@ Windmill Community Edition {GIT_VERSION}
let instance_name = rd_string(8);
schedule_stats(instance_name, mode, &db, &HTTP_CLIENT).await;
futures::try_join!(shutdown_signal, server_f, metrics_f, workers_f, monitor_f)?;
futures::try_join!(shutdown_signal, workers_f, monitor_f, server_f, metrics_f)?;
} else {
tracing::info!("Nothing to do, exiting.");
}

View File

@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.223.1
version: 1.224.0
title: Windmill API
contact:

View File

@@ -29,6 +29,7 @@ pub struct FlowStatus {
pub step: i32,
pub modules: Vec<FlowStatusModule>,
pub failure_module: FlowStatusModuleWParent,
#[serde(default)]
pub cleanup_module: FlowCleanupModule,
#[serde(default)]
#[serde(skip_serializing_if = "is_retry_default")]
@@ -97,13 +98,11 @@ pub struct FlowStatusModuleWParent {
pub module_status: FlowStatusModule,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct FlowCleanupModule {
#[serde(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub flow_jobs_to_clean: Vec<Uuid>,
#[serde(flatten)]
pub module_status: FlowStatusModule,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -228,16 +227,7 @@ impl FlowStatus {
.unwrap_or_else(|| "failure".to_string()),
},
},
cleanup_module: FlowCleanupModule {
flow_jobs_to_clean: vec![],
module_status: FlowStatusModule::WaitingForPriorSteps {
id: f
.failure_module
.as_ref()
.map(|x| x.id.clone())
.unwrap_or_else(|| "cleanup".to_string()),
},
},
cleanup_module: FlowCleanupModule { flow_jobs_to_clean: vec![] },
retry: RetryStatus { fail_count: 0, failed_jobs: vec![] },
restarted_from: None,
}

View File

@@ -89,7 +89,7 @@ pub async fn reload_custom_tags_setting(db: &DB) -> error::Result<()> {
let custom_tags = process_custom_tags(tags);
tracing::info!(
"Loaded setting custom tags, common: {:?}, per-workspace: {:?}",
"Loaded setting custom_tags, common: {:?}, per-workspace: {:?}",
custom_tags.0,
custom_tags.1,
);

View File

@@ -2449,12 +2449,7 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection
id: "failure".to_string(),
},
},
cleanup_module: FlowCleanupModule {
module_status: FlowStatusModule::WaitingForPriorSteps {
id: "cleanup".to_string(),
},
flow_jobs_to_clean: vec![],
},
cleanup_module: FlowCleanupModule { flow_jobs_to_clean: vec![] },
// retry status is reset
retry: RetryStatus { fail_count: 0, failed_jobs: vec![] },
// TODO: for now, flows with approval conditions aren't supported for restart
@@ -2540,12 +2535,7 @@ pub async fn push<'c, T: Serialize + Send + Sync, R: rsmq_async::RsmqConnection
id: "failure".to_string(),
},
},
cleanup_module: FlowCleanupModule {
module_status: FlowStatusModule::WaitingForPriorSteps {
id: "cleanup".to_string(),
},
flow_jobs_to_clean: vec![],
},
cleanup_module: FlowCleanupModule { flow_jobs_to_clean: vec![] },
// retry status is reset
retry: RetryStatus { fail_count: 0, failed_jobs: vec![] },
// TODO: for now, flows with approval conditions aren't supported for restart

View File

@@ -27,7 +27,7 @@ use tokio::sync::mpsc::Sender;
use tracing::instrument;
use uuid::Uuid;
use windmill_common::flow_status::{
ApprovalConditions, FlowCleanupModule, FlowStatusModuleWParent, Iterator, JobResult,
ApprovalConditions, FlowStatusModuleWParent, Iterator, JobResult,
};
use windmill_common::flows::add_virtual_items_if_necessary;
use windmill_common::jobs::{
@@ -168,7 +168,15 @@ pub async fn update_flow_status_after_job_completion_internal<
rsmq: Option<R>,
worker_name: &str,
) -> error::Result<Option<RecUpdateFlowStatusAfterJobCompletion>> {
let (should_continue_flow, flow_job, stop_early, skip_if_stop_early, nresult, is_failure_step) = {
let (
should_continue_flow,
flow_job,
stop_early,
skip_if_stop_early,
nresult,
is_failure_step,
cleanup_module,
) = {
// tracing::debug!("UPDATE FLOW STATUS: {flow:?} {success} {result:?} {w_id} {depth}");
let old_status_json = sqlx::query_scalar!(
@@ -574,6 +582,7 @@ pub async fn update_flow_status_after_job_completion_internal<
skip_if_stop_early,
nresult,
is_failure_step,
old_status.cleanup_module,
)
};
@@ -591,8 +600,7 @@ pub async fn update_flow_status_after_job_completion_internal<
#[cfg(feature = "enterprise")]
if flow_job.parent_job.is_none() {
// run the cleanup step only when the root job is complete
let cleanup_module = retrieve_cleanup_module(flow, db).await?;
if cleanup_module.flow_jobs_to_clean.len() > 0 {
if !cleanup_module.flow_jobs_to_clean.is_empty() {
tracing::debug!(
"Cleaning up jobs arguments, result and logs as they were marked as delete_after_use {:?}",
cleanup_module.flow_jobs_to_clean
@@ -837,26 +845,26 @@ async fn has_failure_module<'c>(
.map(|v| v.unwrap_or(false))
}
async fn retrieve_cleanup_module<'c>(flow_uuid: Uuid, db: &DB) -> Result<FlowCleanupModule, Error> {
tracing::warn!("Retrieving cleanup module of flow {}", flow_uuid);
let raw_value = sqlx::query_scalar!(
"SELECT flow_status->'cleanup_module' as cleanup_module
FROM queue
WHERE id = $1",
flow_uuid,
)
.fetch_one(db)
.await
.map_err(|e| Error::InternalErr(format!("error during retrieval of cleanup module: {e}")))?;
// async fn retrieve_cleanup_module<'c>(flow_uuid: Uuid, db: &DB) -> Result<FlowCleanupModule, Error> {
// tracing::warn!("Retrieving cleanup module of flow {}", flow_uuid);
// let raw_value = sqlx::query_scalar!(
// "SELECT flow_status->'cleanup_module' as cleanup_module
// FROM queue
// WHERE id = $1",
// flow_uuid,
// )
// .fetch_one(db)
// .await
// .map_err(|e| Error::InternalErr(format!("error during retrieval of cleanup module: {e}")))?;
raw_value
.clone()
.and_then(|rv| serde_json::from_value::<FlowCleanupModule>(rv).ok())
.ok_or(Error::InternalErr(format!(
"Unable to parse flow cleanup module {:?}",
raw_value
)))
}
// raw_value
// .clone()
// .and_then(|rv| serde_json::from_value::<FlowCleanupModule>(rv).ok())
// .ok_or(Error::InternalErr(format!(
// "Unable to parse flow cleanup module {:?}",
// raw_value
// )))
// }
fn next_retry(retry: &Retry, status: &RetryStatus) -> Option<(u16, Duration)> {
(status.fail_count <= MAX_RETRY_ATTEMPTS)

View File

@@ -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.223.1";
export const VERSION = "v1.224.0";
export async function login(email: string, password: string): Promise<string> {
return await windmill.UserService.login({

View File

@@ -31,7 +31,7 @@ addEventListener("error", (event) => {
}
});
export const VERSION = "v1.223.1";
export const VERSION = "v1.224.0";
let command: any = new Command()
.name("wmill")

View File

@@ -1,12 +1,12 @@
{
"name": "windmill-components",
"version": "1.223.1",
"version": "1.224.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "windmill-components",
"version": "1.223.1",
"version": "1.224.0",
"license": "AGPL-3.0",
"dependencies": {
"@aws-crypto/sha256-js": "^4.0.0",
@@ -14,6 +14,7 @@
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
"@tanstack/svelte-table": "^8.9.9",
"@typescript/ata": "^0.9.4",
"ag-grid-community": "^31.0.0",
"ag-grid-enterprise": "^31.0.0",
"ansi_up": "^5.2.1",
@@ -1618,6 +1619,14 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript/ata": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@typescript/ata/-/ata-0.9.4.tgz",
"integrity": "sha512-PaJ16WouPV/SaA+c0tnOKIqYq24+m93ipl/e0Dkxuianer+ibc5b0/6ZgfCFF8J7QEp57dySMSP9nWOFaCfJnw==",
"peerDependencies": {
"typescript": "^4.4.4"
}
},
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -9066,7 +9075,6 @@
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

View File

@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.223.1",
"version": "1.224.0",
"scripts": {
"dev": "vite dev",
"build": "vite build",
@@ -71,6 +71,9 @@
"yootils": "^0.3.1"
},
"overrides": {
"@typescript/ata": {
"typescript": "$typescript"
},
"@rgossiaux/svelte-headlessui": {
"svelte": "$svelte"
},
@@ -97,6 +100,7 @@
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
"@tanstack/svelte-table": "^8.9.9",
"@typescript/ata": "^0.9.4",
"ag-grid-community": "^31.0.0",
"ag-grid-enterprise": "^31.0.0",
"ansi_up": "^5.2.1",

View File

@@ -0,0 +1,64 @@
<script lang="ts">
import IconedResourceType from './IconedResourceType.svelte'
import Toggle from './Toggle.svelte'
export let value: any
$: enabled = value != undefined
let org = ''
$: changeOrg(org)
function changeOrg(org) {
if (value) {
value = {
...value,
connect_config: {
auth_url: `${org}/api/oidc/authorization`,
token_url: `${org}/api/oidc/token`,
scopes: ['openid', 'profile', 'email', 'groups']
},
login_config: {
auth_url: `${org}/api/oidc/authorization`,
token_url: `${org}/api/oidc/token`,
userinfo_url: `${org}/api/oidc/userinfo`,
scopes: ['openid', 'profile', 'email', 'groups']
}
}
}
}
</script>
<div class="flex flex-col gap-1">
<label class="text-sm font-medium text-primary flex gap-4 items-center"
><div class="w-[120px]"><IconedResourceType name={'authelia'} after={true} /></div><Toggle
checked={enabled}
on:change={(e) => {
if (e.detail) {
value = { id: '', secret: '' }
} else {
value = undefined
}
}}
/></label
>
{#if enabled}
<div class="border rounded p-2">
<label class="block pb-2">
<span class="text-primary font-semibold text-sm"
>Authelia Url ({'AUTHELIA_URL/api/oidc/authorization'})</span
>
<input type="text" placeholder="yourorg" bind:value={org} />
</label>
<label class="block pb-2">
<span class="text-primary font-semibold text-sm">Client Id</span>
<input type="text" placeholder="Client Id" bind:value={value['id']} />
</label>
<label class="block pb-2">
<span class="text-primary font-semibold text-sm">Client Secret </span>
<input type="text" placeholder="Client Secret" bind:value={value['secret']} />
</label>
</div>
{/if}
</div>

View File

@@ -33,6 +33,7 @@
import { CloseAction, ErrorAction, RequestType, NotificationType } from 'vscode-languageclient'
import { MonacoBinding } from 'y-monaco'
import { dbSchemas, type DBSchema, copilotInfo, codeCompletionSessionEnabled } from '$lib/stores'
import { setupTypeAcquisition } from '@typescript/ata'
import {
createHash as randomHash,
@@ -747,6 +748,23 @@
}
)
} else if (lang === 'typescript' && scriptLang !== 'deno') {
ata = setupTypeAcquisition({
projectName: 'TypeScript Playground',
typescript: ts,
logger: console,
delegate: {
receivedFile: addLibraryToRuntime,
progress: (downloaded: number, total: number) => {
// console.log({ dl, ttl })
},
started: () => {
console.log('ATA start')
},
finished: (f) => {
console.log('ATA done')
}
}
})
await connectToLanguageServer(
`${wsProtocol}://${window.location.host}/ws/bun`,
'bun',

View File

@@ -19,6 +19,7 @@
import { AlertTriangle, Plus } from 'lucide-svelte'
import CustomSso from './CustomSso.svelte'
import AuthentikSetting from '$lib/components/AuthentikSetting.svelte'
import AutheliaSetting from '$lib/components/AutheliaSetting.svelte'
export let tab: string = 'Core'
export let hideTabs: boolean = false
@@ -50,7 +51,12 @@
await Promise.all(
Object.entries(settings).map(
async ([_, y]) =>
await Promise.all(y.map(async (x) => [x.key, await getValue(x.key, x.storage)]))
await Promise.all(
y.map(async (x) => [
x.key,
(await getValue(x.key, x.storage)) ?? x.defaultValue?.()
])
)
)
)
).flat()
@@ -217,8 +223,9 @@
<OAuthSetting name="jumpcloud" bind:value={oauths['jumpcloud']} />
<KeycloakSetting bind:value={oauths['keycloak']} />
<AuthentikSetting bind:value={oauths['authentik']} />
<AutheliaSetting bind:value={oauths['authelia']} />
{#each Object.keys(oauths) as k}
{#if !['authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack'].includes(k) && 'login_config' in oauths[k]}
{#if !['authelia', 'authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack'].includes(k) && 'login_config' in oauths[k]}
{#if oauths[k]}
<div class="flex flex-col gap-2 pb-4">
<div class="flex flex-row items-center gap-2">
@@ -283,7 +290,7 @@
<div class="py-1" />
{#each Object.keys(oauths) as k}
{#if !['authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack'].includes(k) && !('login_config' in oauths[k])}
{#if !['authelia', 'authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack'].includes(k) && !('login_config' in oauths[k])}
{#if oauths[k]}
<div class="flex flex-col gap-2 pb-4">
<div class="flex flex-row items-center gap-2">
@@ -450,8 +457,7 @@
{#if hasError}
<span class="text-red-500 text-xs">
Base url must start with http:// or https:// and must NOT end with a
trailing slash.
{setting.error ?? ''}
</span>
{/if}
{:else}

View File

@@ -102,7 +102,7 @@
'wm-currency-input'
),
wrapper: 'w-full windmillapp',
formattedZero: twMerge('text-black windmillapp ', css?.input?.class, 'wm-currency')
formattedZero: twMerge('windmillapp ', css?.input?.class, 'wm-currency')
}}
style={css?.input?.style}
bind:value

View File

@@ -43,12 +43,17 @@
maximumFractionDigits?: number,
minimumFractionDigits?: number
) => {
return new Intl.NumberFormat(locale, {
currency: currency,
style: 'currency',
maximumFractionDigits: maximumFractionDigits || 0,
minimumFractionDigits: minimumFractionDigits || 0
}).format(value)
try {
return new Intl.NumberFormat(locale, {
currency: currency,
style: 'currency',
maximumFractionDigits: maximumFractionDigits || 0,
minimumFractionDigits: minimumFractionDigits || 0
}).format(value)
} catch (e) {
console.error(e)
return 'ERR'
}
}
// Checks if the key pressed is allowed
@@ -64,14 +69,15 @@
}
let inputTarget: HTMLInputElement
const currencyDecimal = new Intl.NumberFormat(locale).format(1.1).charAt(1) // '.' or ','
const isDecimalComma = currencyDecimal === ','
const currencySymbol = formatCurrency(0, 0)
.replace('0', '') // e.g. '$0' > '$'
.replace(/\u00A0/, '') // e.g '0 €' > '€'
// Updates `value` by stripping away the currency formatting
const setUnformattedValue = (event?: KeyboardEvent) => {
const currencyDecimal = new Intl.NumberFormat(locale).format(1.1).charAt(1) // '.' or ','
const isDecimalComma = currencyDecimal === ','
const currencySymbol = formatCurrency(0, 0)
.replace('0', '') // e.g. '$0' > '$'
.replace(/\u00A0/, '') // e.g '0 €' > '€'
if (event) {
// Don't format if the user is typing a `currencyDecimal` point
if (event.key === currencyDecimal) return
@@ -189,7 +195,7 @@
/>
</div>
<style lang="postcss">
<style>
input.currencyInput__formatted {
border: 1px solid #e2e2e2;
padding: 10px;
@@ -197,7 +203,7 @@
}
input.currencyInput__formatted--zero {
color: #333;
@apply text-primary;
}
input.currencyInput__formatted--positive {

View File

@@ -0,0 +1,32 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 335.000000 335.000000" width="24" height="24" >
<title>authelia-svg</title>
<g transform="translate(0.000000,335.000000) scale(0.100000,-0.100000)" fill="#3F51B4" stroke="none">
<path d="M1359 3300 c-142 -23 -312 -83 -477 -170 -422 -222 -751 -668 -836
-1130 -31 -172 -36 -276 -21 -456 20 -235 69 -414 168 -610 56 -112 173 -280
251 -360 67 -70 74 -74 115 -74 57 0 111 49 111 103 0 36 -13 57 -87 141 -57
64 -156 212 -198 296 -50 99 -102 256 -126 383 -31 155 -31 388 0 534 94 447
385 818 795 1014 120 57 239 93 396 119 63 11 125 22 138 25 52 12 81 119 44
165 -15 19 -29 22 -117 25 -55 2 -125 0 -156 -5z"/>
<path d="M2049 2801 c-23 -24 -29 -38 -29 -73 0 -56 19 -82 83 -114 281 -142
464 -357 552 -649 34 -113 61 -145 122 -145 33 0 50 7 75 29 30 27 33 34 31
83 -3 102 -83 298 -184 453 -64 98 -229 264 -324 326 -188 124 -269 147 -326
90z"/>
<path d="M1030 2750 c-113 -68 -175 -118 -263 -209 -315 -330 -418 -808 -271
-1256 136 -417 487 -726 929 -821 98 -20 360 -24 454 -5 321 63 602 234 785
478 85 114 151 244 151 301 0 58 -45 102 -104 102 -55 0 -84 -27 -136 -129
-180 -348 -561 -567 -950 -548 -241 12 -474 110 -657 276 -130 118 -237 296
-285 477 -23 88 -26 119 -27 269 -1 148 2 181 22 255 28 101 93 242 152 331
59 88 191 215 279 269 41 25 92 62 114 83 37 35 39 40 34 80 -4 30 -15 50 -37
70 -47 42 -90 37 -190 -23z"/>
<path d="M1528 2494 c-312 -56 -570 -293 -652 -599 -24 -87 -31 -249 -16 -342
53 -330 298 -595 623 -673 158 -38 369 -22 512 40 177 76 329 219 415 391 187
371 69 825 -273 1053 -186 124 -396 169 -609 130z m216 -266 c25 -8 59 -31 86
-58 94 -94 94 -219 -1 -313 l-48 -49 64 -261 c72 -291 72 -297 12 -355 -43
-42 -105 -62 -191 -62 -115 0 -206 56 -221 137 -4 17 19 129 58 287 l65 258
-41 37 c-103 93 -103 245 1 332 67 56 135 71 216 47z"/>
<path d="M3034 2306 c-42 -42 -43 -69 -9 -159 50 -135 69 -256 69 -457 1 -206
-10 -279 -69 -457 -118 -354 -379 -654 -714 -823 -96 -48 -283 -106 -401 -125
-158 -25 -178 -32 -200 -68 -61 -99 20 -179 165 -162 702 79 1290 633 1421
1340 25 134 25 437 0 575 -26 150 -80 311 -114 343 -43 41 -103 38 -148 -7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -67,6 +67,7 @@ import AzureIcon from './AzureIcon.svelte'
import OktaIcon from './OktaIcon.svelte'
import MsSqlServerIcon from './MSSqlServerIcon.svelte'
import AuthentikIcon from './AuthentikIcon.svelte';
import AutheliaIcon from './AutheliaIcon.svelte';
export const APP_TO_ICON_COMPONENT = {
postgresql: PostgresIcon,
@@ -140,7 +141,8 @@ export const APP_TO_ICON_COMPONENT = {
nocodb: NocoDbIcon,
azure: AzureIcon,
okta: OktaIcon,
authentik: AuthentikIcon
authentik: AuthentikIcon,
authelia: AutheliaIcon
} as const
export {
@@ -207,5 +209,6 @@ export {
AzureIcon,
MicrosoftIcon,
OktaIcon,
AuthentikIcon
AuthentikIcon,
AutheliaIcon
}

View File

@@ -18,6 +18,8 @@ export interface Setting {
| 'license_key'
storage: SettingStorage
isValid?: (value: any) => boolean
error?: string
defaultValue?: () => any
}
export type SettingStorage = 'setting' | 'config'
@@ -32,7 +34,8 @@ export const settings: Record<string, Setting[]> = {
placeholder: 'https://windmill.com',
storage: 'setting',
isValid: (value: string | undefined) =>
value ? value?.startsWith('http') && value.includes('://') && !value?.endsWith('/') : true
value ? value?.startsWith('http') && value.includes('://') && !value?.endsWith('/') : true,
defaultValue: () => window.location.origin
},
{
label: 'Request Size Limit In MB',

View File

@@ -4,8 +4,8 @@ verify_ssl = true
name = "pypi"
[packages]
wmill = ">=1.223.1"
wmill_pg = ">=1.223.1"
wmill = ">=1.224.0"
wmill_pg = ">=1.224.0"
sendgrid = "*"
mysql-connector-python = "*"
pymongo = "*"

View File

@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.223.1
version: 1.224.0
title: OpenFlow Spec
contact:
name: Ruben Fiszel

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill"
version = "1.223.1"
version = "1.224.0"
description = "A client library for accessing Windmill server wrapping the Windmill client API"
license = "Apache-2.0"
homepage = "https://windmill.dev"
@@ -16,7 +16,7 @@ include = ["wmill/py.typed"]
[tool.poetry.dependencies]
python = "^3.7"
httpx = "^0.25"
httpx = "^0.24"
[build-system]
requires = ["poetry>=1.0.2", "poetry-dynamic-versioning"]

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill-pg"
version = "1.223.1"
version = "1.224.0"
description = "An extension client for the wmill client library focused on pg"
license = "Apache-2.0"
homepage = "https://windmill.dev"

View File

@@ -1,7 +1,7 @@
{
"name": "windmill-client",
"description": "Windmill SDK client for browsers and Node.js",
"version": "1.223.1",
"version": "1.224.0",
"author": "Ruben Fiszel",
"license": "Apache 2.0",
"devDependencies": {

View File

@@ -1 +1 @@
1.223.1
1.224.0