Merge branch 'main' into feat-mailbox

This commit is contained in:
Pyra
2025-10-28 14:49:30 +01:00
committed by GitHub
133 changed files with 1835 additions and 1106 deletions
+30
View File
@@ -1,5 +1,35 @@
# Changelog
## [1.567.2](https://github.com/windmill-labs/windmill/compare/v1.567.1...v1.567.2) (2025-10-28)
### Bug Fixes
* add grant all to concurrency_counter ([c78cb1f](https://github.com/windmill-labs/windmill/commit/c78cb1fb7a93a5ecbb4e7e70705fd1147059898a))
## [1.567.1](https://github.com/windmill-labs/windmill/compare/v1.567.0...v1.567.1) (2025-10-27)
### Bug Fixes
* avoid listing queued jobs if an end bound is set ([a6a0af3](https://github.com/windmill-labs/windmill/commit/a6a0af3298049dcf93663c5ac659e5e2cabf3ffd))
## [1.567.0](https://github.com/windmill-labs/windmill/compare/v1.566.1...v1.567.0) (2025-10-27)
### Features
* is_admin non propagation + change endpoint for forks ([#6958](https://github.com/windmill-labs/windmill/issues/6958)) ([663bc3b](https://github.com/windmill-labs/windmill/commit/663bc3b19ac23938c64b71a0ac10b19d9d6e6d62))
### Bug Fixes
* **cli:** fix generate-metadata wasm parsers ([a9b99e9](https://github.com/windmill-labs/windmill/commit/a9b99e9467a17f056f3cd325dc5dfee0a5ae9caa))
* fix windows bun bundler main.ts path detection ([#6962](https://github.com/windmill-labs/windmill/issues/6962)) ([038986d](https://github.com/windmill-labs/windmill/commit/038986d0b593b5aa172f6c1d2d19337ff0239e4c))
* **frontend:** add transparency to color palette ([#6947](https://github.com/windmill-labs/windmill/issues/6947)) ([a12c278](https://github.com/windmill-labs/windmill/commit/a12c2788ecc1273bb8d98f50520cb1a28e6de280))
* **frontend:** larger object limit for pdfs and files ([#6961](https://github.com/windmill-labs/windmill/issues/6961)) ([4bf2329](https://github.com/windmill-labs/windmill/commit/4bf23294f8ff4998e75108d974447b3b3e147c45))
* improve jobs runs page performance ([#6942](https://github.com/windmill-labs/windmill/issues/6942)) ([5b315bf](https://github.com/windmill-labs/windmill/commit/5b315bf2c8e3d992ca690f994cea2205541ab5ae))
## [1.566.1](https://github.com/windmill-labs/windmill/compare/v1.566.0...v1.566.1) (2025-10-25)
@@ -1,17 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO usr\n (workspace_id, email, username, is_admin)\n VALUES ($1, $2, $3, $4)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Varchar",
"Bool"
]
},
"nullable": []
},
"hash": "0ae9160591ae00117d20a616cfe07e38f0c32953c7e881e916c389255190b72d"
}
@@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO usr\n (workspace_id, email, username, is_admin)\n SELECT $1, email, username, is_admin FROM usr\n WHERE workspace_id = $3 AND email = $2\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "1a9f2ed5045016a3953db335957b26f41efc8a3cad7af7bc8fe97df6a5bf5078"
}
@@ -1,12 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "create index concurrently if not exists ix_job_created_at ON v2_job (created_at DESC)",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "3a5edf3dd884b5a8862bb112f6520967ed4a218782192c6c6fc1498f45d753a6"
}
@@ -0,0 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_started_at_new_2",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "3dca0aded0ec744b084359e1a77dc4af312fda13d832f9e8b236655628e5b81c"
}
@@ -15,7 +15,7 @@
]
},
"nullable": [
true
null
]
},
"hash": "5a219a2532517869578c4504ff3153c43903f929ae5d62fbba12610f89c36d55"
@@ -0,0 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "create index concurrently if not exists ix_job_workspace_id_completed_at_all ON v2_job_completed (workspace_id, completed_at DESC)",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "5c403799772e1c44bd00e5376893a6428b3c7cbdef4af70a6660c1a5900d17a6"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "create index concurrently if not exists ix_v2_job_workspace_id_created_at ON v2_job (workspace_id, created_at DESC) where kind in ('script', 'flow', 'singlescriptflow') AND parent_job IS NULL",
"query": "create index concurrently if not exists ix_v2_job_workspace_id_created_at ON v2_job (workspace_id, created_at DESC) where kind in ('script', 'flow', 'singlestepflow') AND parent_job IS NULL",
"describe": {
"columns": [],
"parameters": {
@@ -8,5 +8,5 @@
},
"nullable": []
},
"hash": "d585aa6301c41308b02a1f0fbf068221e732e48dfa6e34d5b025adbbdcbb03e0"
"hash": "5d99d2b058d4896f9ac1cea04fa35c003bc4e897ee01746d6f17aeee387d1505"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n schedule.path, t.jobs FROM schedule,\n LATERAL(SELECT ARRAY(\n SELECT json_build_object('id', id, 'success', status = 'success', 'duration_ms', duration_ms)\n FROM v2_job_completed c JOIN v2_job j USING (id)\n WHERE trigger_kind = 'schedule'\n AND trigger = schedule.path\n AND c.workspace_id = $1\n AND j.workspace_id = $1\n AND parent_job IS NULL AND runnable_path = schedule.script_path\n AND status <> 'skipped'\n ORDER BY created_at DESC\n LIMIT 20\n ) AS jobs) t\n WHERE workspace_id = $1\n ORDER BY edited_at DESC\n LIMIT $2 OFFSET $3",
"query": "SELECT\n schedule.path, t.jobs FROM schedule,\n LATERAL(SELECT ARRAY(\n SELECT json_build_object('id', id, 'success', status = 'success', 'duration_ms', duration_ms)\n FROM v2_job_completed c JOIN v2_job j USING (id)\n WHERE trigger_kind = 'schedule'\n AND trigger = schedule.path\n AND c.workspace_id = $1\n AND j.workspace_id = $1\n AND parent_job IS NULL AND runnable_path = schedule.script_path\n AND status <> 'skipped'\n ORDER BY completed_at DESC\n LIMIT 20\n ) AS jobs) t\n WHERE workspace_id = $1\n ORDER BY edited_at DESC\n LIMIT $2 OFFSET $3",
"describe": {
"columns": [
{
@@ -26,5 +26,5 @@
null
]
},
"hash": "430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3"
"hash": "5e6dcb3e7a9bc174a040cfba96555eb5140c563a2b191714ef9028b56391b794"
}
@@ -1,16 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO script\n (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, no_main_func, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets)\n\n SELECT workspace_id, $1, path, array_prepend($2::bigint, COALESCE(parent_hashes, '{}'::bigint[])), summary, description, content, created_by, schema, is_template, extra_perms, NULL, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled, delete_after_use, timeout, concurrency_key, visible_to_runner_only, no_main_func, codebase, has_preprocessor, on_behalf_of_email, schema_validation, assets\n\n FROM script WHERE hash = $2 AND workspace_id = $3;\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"Text"
]
},
"nullable": []
},
"hash": "69550451b86f221a3d2ef626be7073fc77421710992b10f526aa36bc64ff0930"
}
@@ -0,0 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "DROP INDEX CONCURRENTLY IF EXISTS ix_job_created_at",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "6ad24aef02d86ea507d232ad0bbf798240d4fcdd52ce2745532ca30f736d25ca"
}
@@ -1,12 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "create index concurrently if not exists ix_completed_job_workspace_id_started_at_new_2 ON v2_job_completed (workspace_id, started_at DESC)",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "931703a98d2ee5fb58d3380896baaee032e731db1e6bd49d991a54f49ab8fa46"
}
@@ -0,0 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "DROP INDEX CONCURRENTLY IF EXISTS ix_v2_job_root_by_path",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "ea9385509319f66b9330221eb50b85edafb9408d0306f17bb78b65a5d81c570b"
}
@@ -0,0 +1,12 @@
{
"db_name": "PostgreSQL",
"query": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_job_v2_job_root_by_path_2 ON v2_job (workspace_id, runnable_path) WHERE parent_job IS NULL;",
"describe": {
"columns": [],
"parameters": {
"Left": []
},
"nullable": []
},
"hash": "f17c9fed09897191ee70214223d4b83a05f1d649bfedff9f24cc3e6c702d42df"
}
+79 -85
View File
@@ -223,6 +223,15 @@ version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "ar_archive_writer"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
dependencies = [
"object 0.32.2",
]
[[package]]
name = "arbitrary"
version = "1.4.2"
@@ -1253,7 +1262,7 @@ dependencies = [
"cfg-if",
"libc",
"miniz_oxide 0.8.9",
"object",
"object 0.37.3",
"rustc-demangle",
"windows-link 0.2.1",
]
@@ -1702,9 +1711,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.12.0"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
dependencies = [
"memchr",
"serde",
@@ -5011,18 +5020,18 @@ dependencies = [
[[package]]
name = "enum-ordinalize"
version = "4.3.0"
version = "4.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0"
dependencies = [
"enum-ordinalize-derive",
]
[[package]]
name = "enum-ordinalize-derive"
version = "4.3.1"
version = "4.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631"
dependencies = [
"proc-macro2",
"quote",
@@ -7188,9 +7197,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.81"
version = "0.3.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -8898,6 +8907,15 @@ dependencies = [
"malloc_buf",
]
[[package]]
name = "object"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.37.3"
@@ -10112,10 +10130,11 @@ dependencies = [
[[package]]
name = "psm"
version = "0.1.27"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c"
checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01"
dependencies = [
"ar_archive_writer",
"cc",
]
@@ -11192,9 +11211,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
dependencies = [
"web-time",
"zeroize",
@@ -14778,9 +14797,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
[[package]]
name = "wasm-bindgen"
version = "0.2.104"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819"
dependencies = [
"cfg-if",
"once_cell",
@@ -14791,9 +14810,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.104"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c"
dependencies = [
"bumpalo",
"log",
@@ -14805,9 +14824,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.54"
version = "0.4.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67"
dependencies = [
"cfg-if",
"js-sys",
@@ -14818,9 +14837,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.104"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -14828,9 +14847,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.104"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32"
dependencies = [
"proc-macro2",
"quote",
@@ -14841,18 +14860,18 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.104"
version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-bindgen-test"
version = "0.3.54"
version = "0.3.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e381134e148c1062f965a42ed1f5ee933eef2927c3f70d1812158f711d39865"
checksum = "aee0a0f5343de9221a0d233b04520ed8dc2e6728dce180b1dcd9288ec9d9fa3c"
dependencies = [
"js-sys",
"minicov",
@@ -14863,9 +14882,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.54"
version = "0.3.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b673bca3298fe582aeef8352330ecbad91849f85090805582400850f8270a2e8"
checksum = "a369369e4360c2884c3168d22bded735c43cccae97bbc147586d4b480edd138d"
dependencies = [
"proc-macro2",
"quote",
@@ -14912,9 +14931,9 @@ dependencies = [
[[package]]
name = "web-sys"
version = "0.3.81"
version = "0.3.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -15123,7 +15142,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windmill"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"aws-sdk-config",
@@ -15183,7 +15202,7 @@ dependencies = [
[[package]]
name = "windmill-api"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"argon2",
@@ -15303,7 +15322,7 @@ dependencies = [
[[package]]
name = "windmill-api-client"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"base64 0.22.1",
"chrono",
@@ -15318,7 +15337,7 @@ dependencies = [
[[package]]
name = "windmill-audit"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"chrono",
"serde",
@@ -15331,7 +15350,7 @@ dependencies = [
[[package]]
name = "windmill-autoscaling"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"axum",
@@ -15350,7 +15369,7 @@ dependencies = [
[[package]]
name = "windmill-common"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"async-recursion",
@@ -15435,7 +15454,7 @@ dependencies = [
[[package]]
name = "windmill-git-sync"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"regex",
"serde",
@@ -15450,7 +15469,7 @@ dependencies = [
[[package]]
name = "windmill-indexer"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"bytes",
@@ -15474,7 +15493,7 @@ dependencies = [
[[package]]
name = "windmill-macros"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"itertools 0.14.0",
"lazy_static",
@@ -15486,7 +15505,7 @@ dependencies = [
[[package]]
name = "windmill-parser"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"convert_case 0.6.0",
"serde",
@@ -15495,7 +15514,7 @@ dependencies = [
[[package]]
name = "windmill-parser-bash"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"lazy_static",
@@ -15507,7 +15526,7 @@ dependencies = [
[[package]]
name = "windmill-parser-csharp"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"serde_json",
@@ -15519,7 +15538,7 @@ dependencies = [
[[package]]
name = "windmill-parser-go"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"gosyn",
@@ -15531,7 +15550,7 @@ dependencies = [
[[package]]
name = "windmill-parser-graphql"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"lazy_static",
@@ -15543,7 +15562,7 @@ dependencies = [
[[package]]
name = "windmill-parser-java"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"serde_json",
@@ -15555,7 +15574,7 @@ dependencies = [
[[package]]
name = "windmill-parser-nu"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"nu-parser",
@@ -15566,7 +15585,7 @@ dependencies = [
[[package]]
name = "windmill-parser-php"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"itertools 0.14.0",
@@ -15577,7 +15596,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"itertools 0.14.0",
@@ -15589,7 +15608,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py-imports"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"async-recursion",
@@ -15612,7 +15631,7 @@ dependencies = [
[[package]]
name = "windmill-parser-ruby"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"lazy_static",
@@ -15626,7 +15645,7 @@ dependencies = [
[[package]]
name = "windmill-parser-rust"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@@ -15643,7 +15662,7 @@ dependencies = [
[[package]]
name = "windmill-parser-sql"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"lazy_static",
@@ -15657,7 +15676,7 @@ dependencies = [
[[package]]
name = "windmill-parser-ts"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"lazy_static",
@@ -15673,34 +15692,9 @@ dependencies = [
"windmill-parser",
]
[[package]]
name = "windmill-parser-wasm"
version = "1.566.1"
dependencies = [
"anyhow",
"getrandom 0.2.16",
"serde_json",
"wasm-bindgen",
"wasm-bindgen-test",
"windmill-parser",
"windmill-parser-bash",
"windmill-parser-csharp",
"windmill-parser-go",
"windmill-parser-graphql",
"windmill-parser-java",
"windmill-parser-nu",
"windmill-parser-php",
"windmill-parser-py",
"windmill-parser-ruby",
"windmill-parser-rust",
"windmill-parser-sql",
"windmill-parser-ts",
"windmill-parser-yaml",
]
[[package]]
name = "windmill-parser-yaml"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"serde",
@@ -15711,7 +15705,7 @@ dependencies = [
[[package]]
name = "windmill-queue"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"async-recursion",
@@ -15744,7 +15738,7 @@ dependencies = [
[[package]]
name = "windmill-sql-datatype-parser-wasm"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"wasm-bindgen",
"wasm-bindgen-test",
@@ -15754,7 +15748,7 @@ dependencies = [
[[package]]
name = "windmill-worker"
version = "1.566.1"
version = "1.567.2"
dependencies = [
"anyhow",
"async-once-cell",
@@ -16452,9 +16446,9 @@ dependencies = [
[[package]]
name = "xml-rs"
version = "0.8.27"
version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7"
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
[[package]]
name = "xmlparser"
+3 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "windmill"
version = "1.566.1"
version = "1.567.2"
authors.workspace = true
edition.workspace = true
@@ -18,7 +18,6 @@ members = [
"./windmill-macros",
"./parsers/windmill-parser",
"./parsers/windmill-parser-ts",
"./parsers/windmill-parser-wasm",
"./parsers/windmill-parser-go",
"./parsers/windmill-parser-rust",
"./parsers/windmill-parser-csharp",
@@ -34,7 +33,7 @@ members = [
exclude = ["./windmill-duckdb-ffi-internal"]
[workspace.package]
version = "1.566.1"
version = "1.567.2"
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
edition = "2021"
@@ -331,7 +330,7 @@ once_cell = "1.17.1"
gosyn = "0.2.6"
bytes = "1.4.0"
gethostname = "0.4.3"
wasm-bindgen = "^0"
wasm-bindgen = "=0.2.103"
serde-wasm-bindgen = "^0"
wasm-bindgen-test = "^0"
convert_case = "0.6.0"
+1 -1
View File
@@ -1 +1 @@
05367c1465d9839ebc79bc22aba68effdde1594e
7ddcee0a4fb8d36494a86b72d2db328a3e9a59ec
@@ -0,0 +1 @@
-- Add down migration script here
@@ -0,0 +1,291 @@
-- Add up migration script here
UPDATE script SET content = 'import * as wmill from "windmill-cli@1.566.1"
export async function main() {
await wmill.hubPull({ workspace: "admins", token: process.env["WM_TOKEN"], baseUrl: process.env["BASE_URL"] });
}
', language = 'bun',
lock = '{
"dependencies": {
"windmill-cli": "1.566.1"
}
}
//bun.lock
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"windmill-cli": "1.566.1",
},
},
},
"packages": {
"@ayonli/jsext": ["@ayonli/jsext@1.9.0", "", { "dependencies": { "iconv-lite": "^0.6.3", "sudo-prompt": "^9.2.1", "ws": "^8.17.0", "zod": "^3.23.8" } }, "sha512-hIu6lQhoLr5e26lmt+vzopuZffaAyb623r4+8HlN/rhXgm2ywHslzk7UHiATdfDbfPjBARkB6cfXjVEi3aav6g=="],
"@deno/shim-deno": ["@deno/shim-deno@0.18.2", "", { "dependencies": { "@deno/shim-deno-test": "^0.5.0", "which": "^4.0.0" } }, "sha512-oQ0CVmOio63wlhwQF75zA4ioolPvOwAoK0yuzcS5bDC1JUvH3y1GS8xPh8EOpcoDQRU4FTG8OQfxhpR+c6DrzA=="],
"@deno/shim-deno-test": ["@deno/shim-deno-test@0.5.0", "", {}, "sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.11", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.11", "", { "os": "android", "cpu": "arm" }, "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.11", "", { "os": "android", "cpu": "arm64" }, "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.11", "", { "os": "android", "cpu": "x64" }, "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.11", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.11", "", { "os": "linux", "cpu": "arm" }, "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.11", "", { "os": "linux", "cpu": "ia32" }, "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.11", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.11", "", { "os": "linux", "cpu": "s390x" }, "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.11", "", { "os": "linux", "cpu": "x64" }, "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ=="],
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.11", "", { "os": "none", "cpu": "x64" }, "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A=="],
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.11", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.11", "", { "os": "openbsd", "cpu": "x64" }, "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw=="],
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.11", "", { "os": "sunos", "cpu": "x64" }, "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.11", "", { "os": "win32", "cpu": "x64" }, "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA=="],
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
"cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"default-browser": ["default-browser@5.2.1", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg=="],
"default-browser-id": ["default-browser-id@5.0.0", "", {}, "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA=="],
"define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-main": ["es-main@1.4.0", "", {}, "sha512-/rYhbfGK/1E6L7TcoUqmrWbSnOlMoxahiZInSYKbhIZ4/dbclHtXEcrViu4Az9IzYNBT8LcXpPszfS47zbGpwA=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"esbuild": ["esbuild@0.25.11", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.11", "@esbuild/android-arm": "0.25.11", "@esbuild/android-arm64": "0.25.11", "@esbuild/android-x64": "0.25.11", "@esbuild/darwin-arm64": "0.25.11", "@esbuild/darwin-x64": "0.25.11", "@esbuild/freebsd-arm64": "0.25.11", "@esbuild/freebsd-x64": "0.25.11", "@esbuild/linux-arm": "0.25.11", "@esbuild/linux-arm64": "0.25.11", "@esbuild/linux-ia32": "0.25.11", "@esbuild/linux-loong64": "0.25.11", "@esbuild/linux-mips64el": "0.25.11", "@esbuild/linux-ppc64": "0.25.11", "@esbuild/linux-riscv64": "0.25.11", "@esbuild/linux-s390x": "0.25.11", "@esbuild/linux-x64": "0.25.11", "@esbuild/netbsd-arm64": "0.25.11", "@esbuild/netbsd-x64": "0.25.11", "@esbuild/openbsd-arm64": "0.25.11", "@esbuild/openbsd-x64": "0.25.11", "@esbuild/openharmony-arm64": "0.25.11", "@esbuild/sunos-x64": "0.25.11", "@esbuild/win32-arm64": "0.25.11", "@esbuild/win32-ia32": "0.25.11", "@esbuild/win32-x64": "0.25.11" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q=="],
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
"express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
"finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-port": ["get-port@7.1.0", "", {}, "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
"is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
"is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
"is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
"isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
"jszip": ["jszip@3.7.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "set-immediate-shim": "~1.0.1" } }, "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg=="],
"lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
"merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
"mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
"minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
"path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"raw-body": ["raw-body@3.0.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.7.0", "unpipe": "1.0.0" } }, "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA=="],
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
"run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
"set-immediate-shim": ["set-immediate-shim@1.0.1", "", {}, "sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ=="],
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
"sudo-prompt": ["sudo-prompt@9.2.1", "", {}, "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw=="],
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
"which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
"windmill-cli": ["windmill-cli@1.566.1", "", { "dependencies": { "@ayonli/jsext": "*", "@deno/shim-deno": "~0.18.0", "diff": "*", "es-main": "*", "esbuild": "*", "express": "*", "get-port": "7.1.0", "jszip": "3.7.1", "minimatch": "*", "open": "*", "ws": "*" }, "bin": { "wmill": "esm/src/main.js" } }, "sha512-dyhcg/fBjOw1GvXxsFI/L+UGgoKTXUBzzVIF7p7HMcNUkD302Uf2l2MwnbJeyYT3czJ8L2oz46/5w2Rq2u/Vhg=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="],
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"raw-body/iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
"readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"string_decoder/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
}
}'
WHERE hash = -28028598712388162 AND workspace_id = 'admins';
@@ -0,0 +1 @@
-- Add down migration script here
@@ -0,0 +1,3 @@
-- Add up migration script here
GRANT ALL ON concurrency_counter TO windmill_admin;
GRANT ALL ON concurrency_counter TO windmill_user;
@@ -1,10 +1,11 @@
cargo-features = ["panic-immediate-abort"]
[package]
name = "windmill-parser-wasm"
version.workspace = true
edition.workspace = true
authors.workspace = true
[lib]
crate-type = ["cdylib"]
name = "windmill_parser_wasm"
@@ -15,6 +16,13 @@ wasm-bindgen-test.workspace = true
windmill-parser-ts.workspace = true
windmill-parser-bash.workspace = true
[profile.release]
panic = "immediate-abort"
[unstable]
build-std = ["std", "panic_abort"]
[features]
default = []
go-parser = [ "dep:windmill-parser-go"]
@@ -48,5 +56,6 @@ windmill-parser-nu = { workspace = true, optional = true }
windmill-parser-java = { workspace = true, optional = true }
windmill-parser-ruby = { workspace = true, optional = true }
wasm-bindgen.workspace = true
serde_json.workspace = true
getrandom = { workspace = true, features = ["js"] }
@@ -112,7 +112,7 @@ def main [
print $"Building in ($profile) mode ($env.OUT_DIR)"
match $t.env {
"default" => {
wasm-pack build ($profile) --target ($tar) --out-dir $env.OUT_DIR --features ($t.features) -Z build-std=panic_abort,std -Z build-std-features=panic_immediate_abort
wasm-pack build --weak-refs ($profile) --target ($tar) --out-dir $env.OUT_DIR --features ($t.features) -Z build-std=panic_abort,std
},
"tree-sitter" => {
$env.CFLAGS_wasm32_unknown_unknown = $"-I(pwd)/wasm-sysroot -Wbad-function-cast -Wcast-function-type -fno-builtin"
@@ -1,7 +1,7 @@
#[cfg(feature = "ts-parser")]
use serde_json::json;
#[allow(unused_imports)]
use wasm_bindgen::prelude::*;
use wasm_bindgen::prelude::wasm_bindgen;
use windmill_parser::MainArgSignature;
#[cfg(feature = "ts-parser")]
use windmill_parser_ts::{parse_expr_for_ids, parse_expr_for_imports};
+64 -54
View File
@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.566.1
version: 1.567.2
title: Windmill API
contact:
@@ -695,12 +695,14 @@ paths:
schema:
type: string
/workspaces/create_fork:
/w/{workspace}/workspaces/create_fork:
post:
summary: create forked workspace
operationId: createWorkspaceFork
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
requestBody:
description: new forked workspace
required: true
@@ -8058,11 +8060,12 @@ paths:
- $ref: "#/components/parameters/StartedAfter"
- $ref: "#/components/parameters/CreatedBefore"
- $ref: "#/components/parameters/CreatedAfter"
- $ref: "#/components/parameters/CreatedOrStartedBefore"
- $ref: "#/components/parameters/CompletedBefore"
- $ref: "#/components/parameters/CompletedAfter"
- $ref: "#/components/parameters/CreatedBeforeQueue"
- $ref: "#/components/parameters/CreatedAfterQueue"
- $ref: "#/components/parameters/Running"
- $ref: "#/components/parameters/ScheduledForBeforeNow"
- $ref: "#/components/parameters/CreatedOrStartedAfter"
- $ref: "#/components/parameters/CreatedOrStartedAfterCompletedJob"
- $ref: "#/components/parameters/JobKinds"
- $ref: "#/components/parameters/Suspended"
- $ref: "#/components/parameters/ArgsFilter"
@@ -8272,18 +8275,18 @@ paths:
- $ref: "#/components/parameters/StartedAfter"
- $ref: "#/components/parameters/CreatedBefore"
- $ref: "#/components/parameters/CreatedAfter"
- $ref: "#/components/parameters/CreatedOrStartedBefore"
- $ref: "#/components/parameters/CompletedBefore"
- $ref: "#/components/parameters/CompletedAfter"
- $ref: "#/components/parameters/CreatedBeforeQueue"
- $ref: "#/components/parameters/CreatedAfterQueue"
- $ref: "#/components/parameters/Running"
- $ref: "#/components/parameters/ScheduledForBeforeNow"
- $ref: "#/components/parameters/CreatedOrStartedAfter"
- $ref: "#/components/parameters/CreatedOrStartedAfterCompletedJob"
- $ref: "#/components/parameters/JobKinds"
- $ref: "#/components/parameters/Suspended"
- $ref: "#/components/parameters/ArgsFilter"
- $ref: "#/components/parameters/Tag"
- $ref: "#/components/parameters/ResultFilter"
- $ref: "#/components/parameters/AllowWildcards"
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PerPage"
- name: is_skipped
description: is the job skipped
@@ -14245,11 +14248,12 @@ paths:
- $ref: "#/components/parameters/ScriptExactHash"
- $ref: "#/components/parameters/StartedBefore"
- $ref: "#/components/parameters/StartedAfter"
- $ref: "#/components/parameters/CreatedOrStartedBefore"
- $ref: "#/components/parameters/Running"
- $ref: "#/components/parameters/ScheduledForBeforeNow"
- $ref: "#/components/parameters/CreatedOrStartedAfter"
- $ref: "#/components/parameters/CreatedOrStartedAfterCompletedJob"
- $ref: "#/components/parameters/CompletedBefore"
- $ref: "#/components/parameters/CompletedAfter"
- $ref: "#/components/parameters/CreatedBeforeQueue"
- $ref: "#/components/parameters/CreatedAfterQueue"
- $ref: "#/components/parameters/JobKinds"
- $ref: "#/components/parameters/ArgsFilter"
- $ref: "#/components/parameters/Tag"
@@ -14838,33 +14842,40 @@ components:
schema:
type: string
format: date-time
CreatedOrStartedAfter:
name: created_or_started_after
description:
filter on created_at for non non started job and started_at otherwise
after (exclusive) timestamp
CompletedBefore:
name: completed_before
description: filter on started before (inclusive) timestamp
in: query
schema:
type: string
format: date-time
CreatedOrStartedAfterCompletedJob:
name: created_or_started_after_completed_jobs
description:
filter on created_at for non non started job and started_at otherwise
after (exclusive) timestamp but only for the completed jobs
CompletedAfter:
name: completed_after
description: filter on started after (exclusive) timestamp
in: query
schema:
type: string
format: date-time
CreatedOrStartedBefore:
name: created_or_started_before
CreatedAfterQueue:
name: created_after_queue
description:
filter on created_at for non non started job and started_at otherwise
before (inclusive) timestamp
filter on jobs created after X for jobs in the queue only
in: query
schema:
type: string
format: date-time
CreatedBeforeQueue:
name: created_before_queue
description:
filter on jobs created before X for jobs in the queue only
in: query
schema:
type: string
format: date-time
Success:
name: success
description: filter on successful jobs
@@ -15669,6 +15680,9 @@ components:
started_at:
type: string
format: date-time
completed_at:
type: string
format: date-time
duration_ms:
type: integer
success:
@@ -16302,30 +16316,30 @@ components:
ScriptLang:
type: string
enum: [
python3,
deno,
go,
bash,
powershell,
postgresql,
mysql,
bigquery,
snowflake,
mssql,
oracledb,
graphql,
nativets,
bun,
php,
rust,
ansible,
csharp,
nu,
java,
ruby,
duckdb,
# for related places search: ADD_NEW_LANG
]
python3,
deno,
go,
bash,
powershell,
postgresql,
mysql,
bigquery,
snowflake,
mssql,
oracledb,
graphql,
nativets,
bun,
php,
rust,
ansible,
csharp,
nu,
java,
ruby,
duckdb,
# for related places search: ADD_NEW_LANG
]
Preview:
type: object
@@ -18413,12 +18427,8 @@ components:
type: string
name:
type: string
username:
type: string
color:
type: string
parent_workspace_id:
type: string
required:
- id
- name
@@ -166,7 +166,7 @@ async fn get_concurrent_intervals(
.clone();
let mut sqlb_c = SqlBuilder::select_from("v2_job_completed")
.fields(UnifiedJob::completed_job_fields())
.order_by("started_at", lq.order_desc.unwrap_or(true))
.order_by("completed_at", lq.order_desc.unwrap_or(true))
.limit(row_limit)
.clone();
let mut sqlb_q_user = SqlBuilder::select_from("v2_job_queue")
@@ -176,7 +176,7 @@ async fn get_concurrent_intervals(
.clone();
let mut sqlb_c_user = SqlBuilder::select_from("v2_job_completed")
.fields(&["id"])
.order_by("started_at", lq.order_desc.unwrap_or(true))
.order_by("completed_at", lq.order_desc.unwrap_or(true))
.limit(row_limit)
.clone();
@@ -209,6 +209,10 @@ async fn get_concurrent_intervals(
started_after: _,
created_before: _,
created_after: _,
created_before_queue: _,
created_after_queue: _,
completed_after: _,
completed_before: _,
created_or_started_before: _,
created_or_started_after: _,
created_or_started_after_completed_jobs: _,
@@ -296,6 +300,7 @@ async fn get_concurrent_intervals(
duration_ms: j.duration_ms,
})
.collect();
let jobs = running_jobs_db
.into_iter()
.filter(|j| running_jobs_user.iter().any(|id| j.id == *id))
@@ -306,6 +311,7 @@ async fn get_concurrent_intervals(
)
.map(From::from)
.collect();
Ok(Json(ExtendedJobs {
jobs,
obscured_jobs,
+51 -30
View File
@@ -778,7 +778,7 @@ macro_rules! get_job_query {
("v2_job_completed", $($opts:tt)*) => {
get_job_query!(
@impl "v2_job_completed", ($($opts)*),
"v2_job_completed.duration_ms, CASE WHEN status = 'success' OR status = 'skipped' THEN true ELSE false END as success, result_columns, deleted, status = 'skipped' as is_skipped, result->'wm_labels' as labels, \
"v2_job_completed.duration_ms, v2_job_completed.completed_at, CASE WHEN status = 'success' OR status = 'skipped' THEN true ELSE false END as success, result_columns, deleted, status = 'skipped' as is_skipped, result->'wm_labels' as labels, \
CASE WHEN result is null or pg_column_size(result) < 90000 THEN result ELSE '\"WINDMILL_TOO_BIG\"'::jsonb END as result",
"",
)
@@ -1820,8 +1820,8 @@ impl From<ListCompletedQuery> for ListQueueQuery {
created_by: lcq.created_by,
started_before: lcq.started_before,
started_after: lcq.started_after,
created_before: lcq.created_before,
created_after: lcq.created_after,
created_before: lcq.created_before_queue.or(lcq.created_before),
created_after: lcq.created_after_queue.or(lcq.created_after),
created_or_started_before: lcq.created_or_started_before,
created_or_started_after: lcq.created_or_started_after,
worker: lcq.worker,
@@ -1855,11 +1855,11 @@ pub fn filter_list_queue_query(
if join_outstanding_wait_times {
sqlb.left()
.join("outstanding_wait_time")
.on_eq("v2_job.id", "outstanding_wait_time.job_id");
.on_eq("v2_job_queue.id", "outstanding_wait_time.job_id");
}
if w_id != "admins" || !lq.all_workspaces.is_some_and(|x| x) {
sqlb.and_where_eq("v2_job.workspace_id", "?".bind(&w_id));
sqlb.and_where_eq("v2_job_queue.workspace_id", "?".bind(&w_id));
}
if let Some(w) = &lq.worker {
@@ -1960,8 +1960,7 @@ pub fn filter_list_queue_query(
}
if lq.is_not_schedule.unwrap_or(false) {
sqlb.and_where("trigger_kind != 'schedule'")
.or_where("trigger_kind IS NULL");
sqlb.and_where("trigger_kind IS DISTINCT FROM 'schedule'");
}
sqlb
@@ -2360,10 +2359,13 @@ async fn list_jobs(
Query(pagination): Query<Pagination>,
Query(lq): Query<ListCompletedQuery>,
) -> error::JsonResult<Vec<Job>> {
let limit = pagination.per_page.unwrap_or(1000);
let (per_page, offset) = paginate(pagination);
let lqc = lq.clone();
if offset > 0 {
tracing::warn!("offset is not 0, but is ignored for list_jobs. Use created_before or completed_before instead.");
}
if lq.success.is_some() && lq.running.is_some_and(|x| x) {
return Err(error::Error::BadRequest(
"cannot specify both success and running".to_string(),
@@ -2372,7 +2374,7 @@ async fn list_jobs(
let sqlc = if lq.running.is_none() {
Some(list_completed_jobs_query(
&w_id,
Some(per_page + offset),
Some(per_page),
0,
&ListCompletedQuery { order_desc: Some(true), ..lqc },
UnifiedJob::completed_job_fields(),
@@ -2385,26 +2387,22 @@ async fn list_jobs(
let sql = if lq.success.is_none()
&& lq.label.is_none()
&& lq.created_or_started_before.is_none()
&& lq.created_before.is_none()
&& lq.started_before.is_none()
&& lq.created_or_started_before.is_none()
&& lq.completed_before.is_none()
{
let mut sqlq = list_queue_jobs_query(
&w_id,
&ListQueueQuery { order_desc: Some(true), ..lq.into() },
UnifiedJob::queued_job_fields(),
Pagination { per_page: Some(limit), page: None },
Pagination { per_page: None, page: None },
true,
get_scope_tags(&authed),
);
if let Some(sqlc) = sqlc {
format!(
"{} UNION ALL {} LIMIT {} OFFSET {};",
&sqlq.subquery()?,
&sqlc.subquery()?,
per_page,
offset
)
format!("{} UNION ALL {}", &sqlq.subquery()?, &sqlc.subquery()?,)
} else {
sqlq.limit(per_page).offset(offset).query()?
}
@@ -2418,6 +2416,7 @@ async fn list_jobs(
}
sqlc.unwrap().limit(per_page).offset(offset).query()?
};
// tracing::info!("sql: {}", sql);
let mut tx: Transaction<'_, Postgres> = user_db.begin(&authed).await?;
let jobs: Vec<UnifiedJob> = sqlx::query_as(&sql)
@@ -3295,6 +3294,7 @@ pub struct UnifiedJob {
pub created_by: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub started_at: Option<chrono::DateTime<chrono::Utc>>,
pub completed_at: Option<chrono::DateTime<chrono::Utc>>,
pub scheduled_for: Option<chrono::DateTime<chrono::Utc>>,
pub running: Option<bool>,
pub script_hash: Option<ScriptHash>,
@@ -3327,13 +3327,14 @@ pub struct UnifiedJob {
const CJ_FIELDS: &[&str] = &[
"'CompletedJob' as typ",
"v2_job.id",
"v2_job.workspace_id",
"v2_job_completed.id",
"v2_job_completed.workspace_id",
"v2_job.parent_job",
"v2_job.created_by",
"v2_job.created_at",
"v2_job_completed.started_at",
"null as scheduled_for",
"v2_job_completed.completed_at",
"null as running",
"v2_job.runnable_id as script_hash",
"v2_job.runnable_path as script_path",
@@ -3366,13 +3367,14 @@ const CJ_FIELDS: &[&str] = &[
const QJ_FIELDS: &[&str] = &[
"'QueuedJob' as typ",
"v2_job.id",
"v2_job.workspace_id",
"v2_job_queue.id",
"v2_job_queue.workspace_id",
"v2_job.parent_job",
"v2_job.created_by",
"v2_job.created_at",
"v2_job_queue.created_at",
"v2_job_queue.started_at",
"v2_job_queue.scheduled_for",
"null as completed_at",
"v2_job_queue.running",
"v2_job.runnable_id as script_hash",
"v2_job.runnable_path as script_path",
@@ -3425,6 +3427,7 @@ impl<'a> From<UnifiedJob> for Job {
created_by: uj.created_by,
created_at: uj.created_at,
started_at: uj.started_at,
completed_at: uj.completed_at,
duration_ms: uj.duration_ms.unwrap(),
success: uj.success.unwrap(),
script_hash: uj.script_hash,
@@ -7507,7 +7510,7 @@ pub fn filter_list_completed_query(
if join_outstanding_wait_times {
sqlb.left()
.join("outstanding_wait_time")
.on_eq("v2_job.id", "outstanding_wait_time.job_id");
.on_eq("v2_job_completed.id", "outstanding_wait_time.job_id");
}
if let Some(label) = &lq.label {
@@ -7535,7 +7538,8 @@ pub fn filter_list_completed_query(
}
if w_id != "admins" || !lq.all_workspaces.is_some_and(|x| x) {
sqlb.and_where_eq("v2_job.workspace_id", "?".bind(&w_id));
sqlb.and_where_eq("v2_job_completed.workspace_id", "?".bind(&w_id))
.and_where_eq("v2_job.workspace_id", "?".bind(&w_id));
}
if let Some(p) = &lq.schedule_path {
@@ -7605,6 +7609,13 @@ pub fn filter_list_completed_query(
sqlb.and_where_ge("started_at", "?".bind(&dt.to_rfc3339()));
}
if let Some(dt) = &lq.completed_after {
sqlb.and_where_ge("completed_at", "?".bind(&dt.to_rfc3339()));
}
if let Some(dt) = &lq.completed_before {
sqlb.and_where_le("completed_at", "?".bind(&dt.to_rfc3339()));
}
if let Some(sk) = &lq.is_skipped {
if *sk {
sqlb.and_where_eq("status", "'skipped'");
@@ -7640,8 +7651,7 @@ pub fn filter_list_completed_query(
}
if lq.is_not_schedule.unwrap_or(false) {
sqlb.and_where("trigger_kind != 'schedule'")
.or_where("trigger_kind IS NULL");
sqlb.and_where("trigger_kind IS DISTINCT FROM 'schedule'");
}
sqlb
@@ -7658,7 +7668,14 @@ pub fn list_completed_jobs_query(
) -> SqlBuilder {
let mut sqlb = SqlBuilder::select_from("v2_job_completed")
.fields(fields)
.order_by("v2_job.created_at", lq.order_desc.unwrap_or(true))
.order_by(
if lq.completed_before.is_some() || lq.completed_after.is_some() {
"v2_job_completed.completed_at"
} else {
"v2_job.created_at"
},
lq.order_desc.unwrap_or(true),
)
.offset(offset)
.clone();
if let Some(per_page) = per_page {
@@ -7687,6 +7704,10 @@ pub struct ListCompletedQuery {
pub created_or_started_before: Option<chrono::DateTime<chrono::Utc>>,
pub created_or_started_after: Option<chrono::DateTime<chrono::Utc>>,
pub created_or_started_after_completed_jobs: Option<chrono::DateTime<chrono::Utc>>,
pub created_before_queue: Option<chrono::DateTime<chrono::Utc>>,
pub created_after_queue: Option<chrono::DateTime<chrono::Utc>>,
pub completed_after: Option<chrono::DateTime<chrono::Utc>>,
pub completed_before: Option<chrono::DateTime<chrono::Utc>>,
pub success: Option<bool>,
pub running: Option<bool>,
pub parent_job: Option<String>,
@@ -7726,8 +7747,8 @@ async fn list_completed_jobs(
offset,
&lq,
&[
"v2_job.id",
"v2_job.workspace_id",
"v2_job_completed.id",
"v2_job_completed.workspace_id",
"v2_job.parent_job",
"v2_job.created_by",
"v2_job.created_at",
+50 -23
View File
@@ -447,19 +447,6 @@ async fn fix_job_completed_index(db: &DB) -> Result<(), Error> {
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("create index concurrently if not exists ix_completed_job_workspace_id_started_at_new_2 ON v2_job_completed (workspace_id, started_at DESC)")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("create index concurrently if not exists ix_job_root_job_index_by_path_2 ON v2_job (workspace_id, runnable_path, created_at desc) WHERE parent_job IS NULL")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS root_job_index_by_path_2")
.execute(db)
.await?;
@@ -467,13 +454,6 @@ async fn fix_job_completed_index(db: &DB) -> Result<(), Error> {
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("create index concurrently if not exists ix_job_created_at ON v2_job (created_at DESC)")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query(
"DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_2",
)
@@ -523,9 +503,9 @@ async fn fix_job_completed_index(db: &DB) -> Result<(), Error> {
});
run_windmill_migration!("v2_improve_v2_job_indices_ii", &db, |tx| {
sqlx::query!("create index concurrently if not exists ix_v2_job_workspace_id_created_at ON v2_job (workspace_id, created_at DESC) where kind in ('script', 'flow', 'singlescriptflow') AND parent_job IS NULL")
.execute(db)
.await?;
sqlx::query!("create index concurrently if not exists ix_v2_job_workspace_id_created_at ON v2_job (workspace_id, created_at DESC) where kind in ('script', 'flow', 'singlestepflow') AND parent_job IS NULL")
.execute(db)
.await?;
sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS ix_job_workspace_id_created_at_new_6")
.execute(db)
@@ -609,5 +589,52 @@ WHERE operation IN ('users.login', 'oauth.login', 'users.token.refresh');"
.execute(db)
.await?;
});
run_windmill_migration!("v2_job_completed_completed_at_9", db, |tx| {
let migration_job_name = "v2_job_completed_completed_at";
let mut i = 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("create index concurrently if not exists ix_job_workspace_id_completed_at_all ON v2_job_completed (workspace_id, completed_at DESC)")
.execute(db)
.await?;
i += 1;
sqlx::query!("CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_job_v2_job_root_by_path_2 ON v2_job (workspace_id, runnable_path) WHERE parent_job IS NULL;")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("create index concurrently if not exists ix_job_root_job_index_by_path_2 ON v2_job (workspace_id, runnable_path, created_at desc) WHERE parent_job IS NULL")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!(
"DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_started_at_new_2"
)
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS ix_job_created_at")
.execute(db)
.await?;
i += 1;
sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS ix_v2_job_root_by_path")
.execute(db)
.await?;
i += 1;
tracing::info!("step {i} of {migration_job_name} migration");
});
Ok(())
}
+1 -1
View File
@@ -583,7 +583,7 @@ async fn list_schedule_with_jobs(
AND j.workspace_id = $1
AND parent_job IS NULL AND runnable_path = schedule.script_path
AND status <> 'skipped'
ORDER BY created_at DESC
ORDER BY completed_at DESC
LIMIT 20
) AS jobs) t
WHERE workspace_id = $1
+15 -33
View File
@@ -141,6 +141,7 @@ pub fn workspaced_service() -> Router {
)
.route("/leave", post(leave_workspace))
.route("/get_workspace_name", get(get_workspace_name))
.route("/create_fork", post(create_workspace_fork))
.route("/change_workspace_name", post(change_workspace_name))
.route("/change_workspace_color", post(change_workspace_color))
.route(
@@ -175,7 +176,7 @@ pub fn global_service() -> Router {
.route("/list", get(list_workspaces))
.route("/users", get(user_workspaces))
.route("/create", post(create_workspace))
.route("/create_fork", post(create_workspace_fork))
.route("/create_fork", post(deprecated_create_workspace_fork))
.route("/exists", post(exists_workspace))
.route("/exists_username", post(exists_username))
.route("/allowed_domain_auto_invite", get(is_allowed_auto_domain))
@@ -341,9 +342,7 @@ struct CreateWorkspace {
struct CreateWorkspaceFork {
id: String,
name: String,
username: Option<String>,
color: Option<String>,
parent_workspace_id: String,
}
#[derive(Deserialize)]
@@ -2898,9 +2897,14 @@ async fn clone_workspace_dependencies(
Ok(())
}
async fn deprecated_create_workspace_fork(_authed: ApiAuthed) -> Result<String> {
return Err(Error::BadRequest("This API endpoint has been relocated. Your Windmill CLI version is outdated and needs to be updated.".to_string()));
}
async fn create_workspace_fork(
authed: ApiAuthed,
Extension(db): Extension<DB>,
Path(parent_workspace_id): Path<String>,
Json(nw): Json<CreateWorkspaceFork>,
) -> Result<String> {
// if *CREATE_WORKSPACE_REQUIRE_SUPERADMIN {
@@ -2925,29 +2929,6 @@ async fn create_workspace_fork(
let forked_id = nw.id;
// Determine username early so we can use it in workspace creation
let automate_username_creation = sqlx::query_scalar!(
"SELECT value FROM global_settings WHERE name = $1",
AUTOMATE_USERNAME_CREATION_SETTING,
)
.fetch_optional(&mut *tx)
.await?
.map(|v| v.as_bool())
.flatten()
.unwrap_or(false);
let username = if automate_username_creation {
if nw.username.is_some() && nw.username.unwrap().len() > 0 {
return Err(Error::BadRequest(
"username is not allowed when username creation is automated".to_string(),
));
}
get_instance_username_or_create_pending(&mut tx, &authed.email).await?
} else {
nw.username
.ok_or(Error::BadRequest("username is required".to_string()))?
};
sqlx::query!(
"INSERT INTO workspace
(id, name, owner, parent_workspace_id)
@@ -2955,7 +2936,7 @@ async fn create_workspace_fork(
forked_id,
nw.name,
authed.email,
nw.parent_workspace_id,
parent_workspace_id,
)
.execute(&mut *tx)
.await?;
@@ -2972,18 +2953,19 @@ async fn create_workspace_fork(
sqlx::query!(
"INSERT INTO usr
(workspace_id, email, username, is_admin)
VALUES ($1, $2, $3, $4)",
(workspace_id, email, username, is_admin)
SELECT $1, email, username, is_admin FROM usr
WHERE workspace_id = $3 AND email = $2
",
forked_id,
authed.email,
username,
authed.is_admin,
parent_workspace_id,
)
.execute(&mut *tx)
.await?;
// Clone all data from the parent workspace using Rust implementation
clone_workspace_data(&mut tx, &nw.parent_workspace_id, &forked_id).await?;
clone_workspace_data(&mut tx, &parent_workspace_id, &forked_id).await?;
sqlx::query!(
"INSERT INTO workspace_invite (workspace_id, email, is_admin, operator)
@@ -2991,7 +2973,7 @@ async fn create_workspace_fork(
FROM usr
WHERE workspace_id = $2",
&forked_id,
&nw.parent_workspace_id
&parent_workspace_id
)
.execute(&mut *tx)
.await?;
+1
View File
@@ -263,6 +263,7 @@ pub struct CompletedJob {
pub created_by: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub started_at: Option<chrono::DateTime<chrono::Utc>>,
pub completed_at: Option<chrono::DateTime<chrono::Utc>>,
pub duration_ms: i64,
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
+1 -2
View File
@@ -2427,8 +2427,7 @@ pub async fn pull(
}
#[cfg(not(feature = "enterprise"))]
let has_concurent_limit = false
|| (job.is_dependency() && job.concurrent_limit.is_some() && cfg!(feature = "private") && !*WMDEBUG_NO_DJOB_DEBOUNCING);
let has_concurent_limit = job.is_dependency() && job.concurrent_limit.is_some() && cfg!(feature = "private") && !*WMDEBUG_NO_DJOB_DEBOUNCING;
// if we don't have private flag, we don't have concurrency limit
// concurrency check. If more than X jobs for this path are already running, we re-queue and pull another job from the queue
+3 -1
View File
@@ -15,8 +15,10 @@ const p = {
const cdir = resolve("./");
const cdirNoPrivate = cdir.replace(/^\/private/, ""); // for macos
// On Windows, normalize path to POSIX format to match args.path from Bun's resolver
const cdirPosix = cdir.replace(/\\/g, "/").replace(/^[a-zA-Z]:/, "");
const filterResolve = new RegExp(
`^(?!\\.\/main\\.ts)(?!${cdir}\/main\\.ts)(?!(?:/private)?${cdirNoPrivate}\/wrapper\\.mjs).*\\.ts$`
`^(?!\\.\/main\\.ts)(?!${cdir}\/main\\.ts)(?!${cdirPosix}\/main\\.ts)(?!(?:/private)?${cdirNoPrivate}\/wrapper\\.mjs).*\\.ts$`
);
let cdirNodeModules = `${cdir}/node_modules/`;
+1 -1
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.566.1";
export const VERSION = "v1.567.2";
export async function login(email: string, password: string): Promise<string> {
return await windmill.UserService.login({
+1 -1
View File
@@ -938,7 +938,7 @@ async function generateMetadata(
scriptPath: string | undefined
) {
log.info(
"This command only works for workspace scripts, for flows inline scripts use `wmill flow generate - locks`"
"This command only works for workspace scripts, for flows inline scripts use `wmill flow generate-locks`"
);
if (scriptPath == "") {
scriptPath = undefined;
+3 -6
View File
@@ -1,9 +1,7 @@
// deno-lint-ignore-file no-explicit-any
import { GlobalOptions } from "../../types.ts";
import { colors, Command, Input, log, setClient } from "../../../deps.ts";
import { requireLogin } from "../../core/auth.ts";
import { add, addWorkspace, allWorkspaces, getActiveWorkspace, list, removeWorkspace } from "./workspace.ts";
import { loginInteractive, tryGetLoginInfo } from "../../core/login.ts";
import { colors, Input, log, setClient } from "../../../deps.ts";
import { addWorkspace, allWorkspaces, list, removeWorkspace } from "./workspace.ts";
import * as wmill from "../../../gen/services.gen.ts";
import { getCurrentGitBranch, getOriginalBranchForWorkspaceForks, isGitRepository } from "../../utils/git.ts";
import { WM_FORK_PREFIX } from "../../main.ts";
@@ -107,12 +105,11 @@ async function createWorkspaceFork(
try {
// TODO: Update to createWorkspaceFork after regenerating client from new OpenAPI spec
const result = await wmill.createWorkspaceFork({
workspace: workspace.workspaceId,
requestBody: {
id: trueWorkspaceId,
name: opts.createWorkspaceName ?? trueWorkspaceId,
username: undefined, // Let the server handle username
color: undefined,
parent_workspace_id: workspace.workspaceId,
},
});
+1 -1
View File
@@ -68,7 +68,7 @@ export {
// }
// });
export const VERSION = "1.566.1";
export const VERSION = "1.567.2";
export const WM_FORK_PREFIX = "wm-fork";
+6 -2
View File
@@ -56,13 +56,17 @@ function passStringToWasm0(arg, malloc, realloc) {
return ptr;
}
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
function decodeText(ptr, len) {
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
return decodeText(ptr, len);
}
/**
* @param {string} code
+125
View File
@@ -0,0 +1,125 @@
let wasm;
export function __wbg_set_wasm(val) {
wasm = val;
}
let WASM_VECTOR_LEN = 0;
let cachedUint8ArrayMemory0 = null;
function getUint8ArrayMemory0() {
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory0;
}
const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder;
const cachedTextEncoder = new lTextEncoder('utf-8');
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length, 1) >>> 0;
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getUint8ArrayMemory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;
let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
const MAX_SAFARI_DECODE_BYTES = 2146435072;
let numBytesDecoded = 0;
function decodeText(ptr, len) {
numBytesDecoded += len;
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
numBytesDecoded = len;
}
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return decodeText(ptr, len);
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_nu(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_nu(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
export function __wbindgen_init_externref_table() {
const table = wasm.__wbindgen_export_0;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
;
};
Binary file not shown.
+9 -9
View File
@@ -1,14 +1,14 @@
/* tslint:disable */
/* eslint-disable */
export function parse_bash(code: string): string;
export function parse_powershell(code: string): string;
export function parse_sql(code: string): string;
export function parse_mysql(code: string): string;
export function parse_oracledb(code: string): string;
export function parse_duckdb(code: string): string;
export function parse_bigquery(code: string): string;
export function parse_snowflake(code: string): string;
export function parse_mssql(code: string): string;
export function parse_db_resource(code: string): string | undefined;
export function parse_graphql(code: string): string;
export function parse_assets_sql(code: string): string;
export function parse_duckdb(code: string): string;
export function parse_graphql(code: string): string;
export function parse_db_resource(code: string): string | undefined;
export function parse_mysql(code: string): string;
export function parse_sql(code: string): string;
export function parse_oracledb(code: string): string;
export function parse_bigquery(code: string): string;
export function parse_mssql(code: string): string;
export function parse_powershell(code: string): string;
+108 -90
View File
@@ -11,7 +11,11 @@ function getUint8ArrayMemory0() {
return cachedUint8ArrayMemory0;
}
const cachedTextEncoder = new TextEncoder();
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
};
function passStringToWasm0(arg, malloc, realloc) {
@@ -42,7 +46,7 @@ function passStringToWasm0(arg, malloc, realloc) {
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = cachedTextEncoder.encodeInto(arg, view);
const ret = encodeString(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
@@ -52,9 +56,9 @@ function passStringToWasm0(arg, malloc, realloc) {
return ptr;
}
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
cachedTextDecoder.decode();
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
function decodeText(ptr, len) {
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
@@ -87,13 +91,13 @@ export function parse_bash(code) {
* @param {string} code
* @returns {string}
*/
export function parse_powershell(code) {
export function parse_snowflake(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_powershell(ptr0, len0);
const ret = wasm.parse_snowflake(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
@@ -106,51 +110,13 @@ export function parse_powershell(code) {
* @param {string} code
* @returns {string}
*/
export function parse_sql(code) {
export function parse_assets_sql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_sql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_mysql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_mysql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_oracledb(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_oracledb(ptr0, len0);
const ret = wasm.parse_assets_sql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
@@ -182,13 +148,48 @@ export function parse_duckdb(code) {
* @param {string} code
* @returns {string}
*/
export function parse_bigquery(code) {
export function parse_graphql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_bigquery(ptr0, len0);
const ret = wasm.parse_graphql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string | undefined}
*/
export function parse_db_resource(code) {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_db_resource(ptr0, len0);
let v2;
if (ret[0] !== 0) {
v2 = getStringFromWasm0(ret[0], ret[1]).slice();
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
}
return v2;
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_mysql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_mysql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
@@ -201,13 +202,51 @@ export function parse_bigquery(code) {
* @param {string} code
* @returns {string}
*/
export function parse_snowflake(code) {
export function parse_sql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_snowflake(ptr0, len0);
const ret = wasm.parse_sql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_oracledb(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_oracledb(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_bigquery(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_bigquery(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
@@ -235,52 +274,17 @@ export function parse_mssql(code) {
}
}
/**
* @param {string} code
* @returns {string | undefined}
*/
export function parse_db_resource(code) {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_db_resource(ptr0, len0);
let v2;
if (ret[0] !== 0) {
v2 = getStringFromWasm0(ret[0], ret[1]).slice();
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
}
return v2;
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_graphql(code) {
export function parse_powershell(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_graphql(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_assets_sql(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_assets_sql(ptr0, len0);
const ret = wasm.parse_powershell(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
@@ -305,9 +309,23 @@ const imports = {
};
const wasmUrl = new URL('windmill_parser_wasm_bg.wasm', import.meta.url);
const wasm = (await WebAssembly.instantiateStreaming(fetch(wasmUrl), imports)).instance.exports;
export { wasm as __wasm };
const wasm_url = new URL('windmill_parser_wasm_bg.wasm', import.meta.url);
let wasmCode = '';
switch (wasm_url.protocol) {
case 'file:':
wasmCode = await Deno.readFile(wasm_url);
break
case 'https:':
case 'http:':
wasmCode = await (await fetch(wasm_url)).arrayBuffer();
break
default:
throw new Error(`Unsupported protocol: ${wasm_url.protocol}`);
}
const wasmInstance = (await WebAssembly.instantiate(wasmCode, imports)).instance;
const wasm = wasmInstance.exports;
export const __wasm = wasm;
wasm.__wbindgen_start();
Binary file not shown.
+8 -8
View File
@@ -1,18 +1,18 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export const parse_assets_sql: (a: number, b: number) => [number, number];
export const parse_bash: (a: number, b: number) => [number, number];
export const parse_powershell: (a: number, b: number) => [number, number];
export const parse_sql: (a: number, b: number) => [number, number];
export const parse_bigquery: (a: number, b: number) => [number, number];
export const parse_db_resource: (a: number, b: number) => [number, number];
export const parse_duckdb: (a: number, b: number) => [number, number];
export const parse_graphql: (a: number, b: number) => [number, number];
export const parse_mssql: (a: number, b: number) => [number, number];
export const parse_mysql: (a: number, b: number) => [number, number];
export const parse_oracledb: (a: number, b: number) => [number, number];
export const parse_duckdb: (a: number, b: number) => [number, number];
export const parse_bigquery: (a: number, b: number) => [number, number];
export const parse_powershell: (a: number, b: number) => [number, number];
export const parse_snowflake: (a: number, b: number) => [number, number];
export const parse_mssql: (a: number, b: number) => [number, number];
export const parse_db_resource: (a: number, b: number) => [number, number];
export const parse_graphql: (a: number, b: number) => [number, number];
export const parse_assets_sql: (a: number, b: number) => [number, number];
export const parse_sql: (a: number, b: number) => [number, number];
export const __wbindgen_export_0: WebAssembly.Table;
export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
+1 -1
View File
@@ -2,5 +2,5 @@
/* eslint-disable */
export function parse_deno(code: string, main_override?: string | null): string;
export function parse_outputs(code: string): string;
export function parse_ts_imports(code: string): string;
export function parse_assets_ts(code: string): string;
export function parse_ts_imports(code: string): string;
+82 -64
View File
@@ -9,9 +9,9 @@ function getUint8ArrayMemory0() {
return cachedUint8ArrayMemory0;
}
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
cachedTextDecoder.decode();
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
function decodeText(ptr, len) {
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
@@ -122,7 +122,11 @@ function debugString(val) {
let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = new TextEncoder();
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
};
function passStringToWasm0(arg, malloc, realloc) {
@@ -153,7 +157,7 @@ function passStringToWasm0(arg, malloc, realloc) {
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = cachedTextEncoder.encodeInto(arg, view);
const ret = encodeString(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
@@ -203,25 +207,6 @@ export function parse_outputs(code) {
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_ts_imports(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_ts_imports(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
@@ -241,37 +226,56 @@ export function parse_assets_ts(code) {
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_ts_imports(code) {
let deferred2_0;
let deferred2_1;
try {
const ptr0 = passStringToWasm0(code, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.parse_ts_imports(ptr0, len0);
deferred2_0 = ret[0];
deferred2_1 = ret[1];
return getStringFromWasm0(ret[0], ret[1]);
} finally {
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
const imports = {
__wbindgen_placeholder__: {
__wbg_Error_e17e777aac105295: function(arg0, arg1) {
__wbg_Error_1f3748b298f99708: function(arg0, arg1) {
const ret = Error(getStringFromWasm0(arg0, arg1));
return ret;
},
__wbg_call_13410aac570ffff7: function() { return handleError(function (arg0, arg1) {
__wbg_call_2f8d426a20a307fe: function() { return handleError(function (arg0, arg1) {
const ret = arg0.call(arg1);
return ret;
}, arguments) },
__wbg_done_75ed0ee6dd243d9d: function(arg0) {
__wbg_done_4a7743b6f942c9f3: function(arg0) {
const ret = arg0.done;
return ret;
},
__wbg_entries_2be2f15bd5554996: function(arg0) {
__wbg_entries_17f7acbc2d691c0d: function(arg0) {
const ret = Object.entries(arg0);
return ret;
},
__wbg_eval_5088487c29e8df77: function(arg0, arg1) {
__wbg_eval_12755dabbdfa08b1: function(arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return ret;
},
__wbg_get_0da715ceaecea5c8: function(arg0, arg1) {
const ret = arg0[arg1 >>> 0];
return ret;
},
__wbg_get_458e874b43b18b25: function() { return handleError(function (arg0, arg1) {
__wbg_get_27b4bcbec57323ca: function() { return handleError(function (arg0, arg1) {
const ret = Reflect.get(arg0, arg1);
return ret;
}, arguments) },
__wbg_instanceof_ArrayBuffer_67f3012529f6a2dd: function(arg0) {
__wbg_get_59c6316d15f9f1d0: function(arg0, arg1) {
const ret = arg0[arg1 >>> 0];
return ret;
},
__wbg_instanceof_ArrayBuffer_59339a3a6f0c10ea: function(arg0) {
let result;
try {
result = arg0 instanceof ArrayBuffer;
@@ -281,7 +285,7 @@ const imports = {
const ret = result;
return ret;
},
__wbg_instanceof_Map_ebb01a5b6b5ffd0b: function(arg0) {
__wbg_instanceof_Map_dd89a82d76d1b25f: function(arg0) {
let result;
try {
result = arg0 instanceof Map;
@@ -291,7 +295,7 @@ const imports = {
const ret = result;
return ret;
},
__wbg_instanceof_Uint8Array_9a8378d955933db7: function(arg0) {
__wbg_instanceof_Uint8Array_91f3c5adee7e6672: function(arg0) {
let result;
try {
result = arg0 instanceof Uint8Array;
@@ -301,95 +305,95 @@ const imports = {
const ret = result;
return ret;
},
__wbg_isArray_030cce220591fb41: function(arg0) {
__wbg_isArray_bc2498eba6fcb71f: function(arg0) {
const ret = Array.isArray(arg0);
return ret;
},
__wbg_isSafeInteger_1c0d1af5542e102a: function(arg0) {
__wbg_isSafeInteger_6091d6e3ee1b65fd: function(arg0) {
const ret = Number.isSafeInteger(arg0);
return ret;
},
__wbg_iterator_f370b34483c71a1c: function() {
__wbg_iterator_96378c3c9a17347c: function() {
const ret = Symbol.iterator;
return ret;
},
__wbg_length_186546c51cd61acd: function(arg0) {
__wbg_length_246fa1f85a0dea5b: function(arg0) {
const ret = arg0.length;
return ret;
},
__wbg_length_6bb7e81f9d7713e4: function(arg0) {
__wbg_length_904c0910ed998bf3: function(arg0) {
const ret = arg0.length;
return ret;
},
__wbg_new_638ebfaedbf32a5e: function(arg0) {
__wbg_new_9190433fb67ed635: function(arg0) {
const ret = new Uint8Array(arg0);
return ret;
},
__wbg_next_5b3530e612fde77d: function(arg0) {
const ret = arg0.next;
return ret;
},
__wbg_next_692e82279131b03c: function() { return handleError(function (arg0) {
__wbg_next_2e6b37020ac5fe58: function() { return handleError(function (arg0) {
const ret = arg0.next();
return ret;
}, arguments) },
__wbg_prototypesetcall_3d4a26c1ed734349: function(arg0, arg1, arg2) {
__wbg_next_3de8f2669431a3ff: function(arg0) {
const ret = arg0.next;
return ret;
},
__wbg_prototypesetcall_c5f74efd31aea86b: function(arg0, arg1, arg2) {
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
},
__wbg_value_dd9372230531eade: function(arg0) {
__wbg_value_09d0b4eaab48b91d: function(arg0) {
const ret = arg0.value;
return ret;
},
__wbg_wbindgenbigintgetasi64_ac743ece6ab9bba1: function(arg0, arg1) {
__wbg_wbindgenbigintgetasi64_7637cb1a7fb9a81e: function(arg0, arg1) {
const v = arg1;
const ret = typeof(v) === 'bigint' ? v : undefined;
getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
},
__wbg_wbindgenbooleanget_3fe6f642c7d97746: function(arg0) {
__wbg_wbindgenbooleanget_59f830b1a70d2530: function(arg0) {
const v = arg0;
const ret = typeof(v) === 'boolean' ? v : undefined;
return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
},
__wbg_wbindgendebugstring_99ef257a3ddda34d: function(arg0, arg1) {
__wbg_wbindgendebugstring_bb652b1bc2061b6d: function(arg0, arg1) {
const ret = debugString(arg1);
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
},
__wbg_wbindgenin_d7a1ee10933d2d55: function(arg0, arg1) {
__wbg_wbindgenin_192b210aa1c401e9: function(arg0, arg1) {
const ret = arg0 in arg1;
return ret;
},
__wbg_wbindgenisbigint_ecb90cc08a5a9154: function(arg0) {
__wbg_wbindgenisbigint_7d76a1ca6454e439: function(arg0) {
const ret = typeof(arg0) === 'bigint';
return ret;
},
__wbg_wbindgenisfunction_8cee7dce3725ae74: function(arg0) {
__wbg_wbindgenisfunction_ea72b9d66a0e1705: function(arg0) {
const ret = typeof(arg0) === 'function';
return ret;
},
__wbg_wbindgenisobject_307a53c6bd97fbf8: function(arg0) {
__wbg_wbindgenisobject_dfe064a121d87553: function(arg0) {
const val = arg0;
const ret = typeof(val) === 'object' && val !== null;
return ret;
},
__wbg_wbindgenjsvaleq_e6f2ad59ccae1b58: function(arg0, arg1) {
__wbg_wbindgenjsvaleq_f27272c0a890df7f: function(arg0, arg1) {
const ret = arg0 === arg1;
return ret;
},
__wbg_wbindgenjsvallooseeq_9bec8c9be826bed1: function(arg0, arg1) {
__wbg_wbindgenjsvallooseeq_9dd7bb4b95ac195c: function(arg0, arg1) {
const ret = arg0 == arg1;
return ret;
},
__wbg_wbindgennumberget_f74b4c7525ac05cb: function(arg0, arg1) {
__wbg_wbindgennumberget_d855f947247a3fbc: function(arg0, arg1) {
const obj = arg1;
const ret = typeof(obj) === 'number' ? obj : undefined;
getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
},
__wbg_wbindgenstringget_0f16a6ddddef376f: function(arg0, arg1) {
__wbg_wbindgenstringget_43fe05afe34b0cb1: function(arg0, arg1) {
const obj = arg1;
const ret = typeof(obj) === 'string' ? obj : undefined;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -397,7 +401,7 @@ const imports = {
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
},
__wbg_wbindgenthrow_451ec1a8469d7eb6: function(arg0, arg1) {
__wbg_wbindgenthrow_4c11a24fca429ccf: function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
},
__wbindgen_cast_4625c577ab2ec9ee: function(arg0) {
@@ -424,9 +428,23 @@ const imports = {
};
const wasmUrl = new URL('windmill_parser_wasm_bg.wasm', import.meta.url);
const wasm = (await WebAssembly.instantiateStreaming(fetch(wasmUrl), imports)).instance.exports;
export { wasm as __wasm };
const wasm_url = new URL('windmill_parser_wasm_bg.wasm', import.meta.url);
let wasmCode = '';
switch (wasm_url.protocol) {
case 'file:':
wasmCode = await Deno.readFile(wasm_url);
break
case 'https:':
case 'http:':
wasmCode = await (await fetch(wasm_url)).arrayBuffer();
break
default:
throw new Error(`Unsupported protocol: ${wasm_url.protocol}`);
}
const wasmInstance = (await WebAssembly.instantiate(wasmCode, imports)).instance;
const wasm = wasmInstance.exports;
export const __wasm = wasm;
wasm.__wbindgen_start();
Binary file not shown.
+1 -1
View File
@@ -1,10 +1,10 @@
/* tslint:disable */
/* eslint-disable */
export const memory: WebAssembly.Memory;
export const parse_assets_ts: (a: number, b: number) => [number, number];
export const parse_deno: (a: number, b: number, c: number, d: number) => [number, number];
export const parse_outputs: (a: number, b: number) => [number, number];
export const parse_ts_imports: (a: number, b: number) => [number, number];
export const parse_assets_ts: (a: number, b: number) => [number, number];
export const __wbindgen_exn_store: (a: number) => void;
export const __externref_table_alloc: () => number;
export const __wbindgen_export_2: WebAssembly.Table;
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "windmill-components",
"version": "1.566.1",
"version": "1.567.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "windmill-components",
"version": "1.566.1",
"version": "1.567.2",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.566.1",
"version": "1.567.2",
"scripts": {
"dev": "vite dev",
"build": "vite build",
+3
View File
@@ -62,6 +62,9 @@
list-style-type: '- ';
padding-left: 3rem;
}
.prose a {
@apply text-accent no-underline;
}
.autocomplete-list-item-create {
@apply !text-primary-inverse !bg-surface-inverse;
+59 -14
View File
@@ -12,7 +12,7 @@
"surface-selected": "#ffffff",
"surface-disabled": "#d8d8e433",
"surface-secondary": "#efeff4",
"surface-hover": "#eeeef4",
"surface-hover": "#cfcfe233",
"surface-primary": "#fbfbfd",
"border-light": "#e5e7eb",
"border-normal": "#9ca3af",
@@ -82,7 +82,7 @@
"surface-selected": "#434c5e",
"surface-disabled": "#212732",
"surface-secondary": "#272c35",
"surface-hover": "#454f64",
"surface-hover": "#7784a119",
"surface-primary": "#2e3441",
"border-light": "#374457",
"border-normal": "#a9b0ba",
@@ -100,7 +100,7 @@
"reserved-ai": "#f0c6fb",
"component-virtual-node": "#4c566a",
"text-accent": "#c7cefc",
"border-selected": "#758ff8",
"border-selected": "#6475b7",
"surface-sunken": "#242832",
"text-tertiary": "#a8aeb7",
"surface-input": "#292e38"
@@ -123,16 +123,16 @@
"deep-blue-200": "#9da6ca",
"deep-blue-100": "#c3c9df",
"deep-blue-50": "#e7eaf2",
"luminance-blue-900": "#1e3a8a",
"luminance-blue-800": "#0d3cc5",
"luminance-blue-700": "#1847d2",
"luminance-blue-600": "#2652df",
"luminance-blue-500": "#2c5beb",
"luminance-blue-400": "#5074f6",
"luminance-blue-300": "#758ff8",
"luminance-blue-200": "#a0affa",
"luminance-blue-100": "#c7cefc",
"luminance-blue-50": "#e9ecfe",
"blue-900": "#1e3a8a",
"blue-800": "#183faf",
"blue-700": "#1847d2",
"blue-600": "#2652df",
"blue-500": "#2c5beb",
"blue-400": "#5074f6",
"blue-300": "#758ff8",
"blue-200": "#a0affa",
"blue-100": "#c7cefc",
"blue-50": "#e9ecfe",
"nord-0": "#2e3440",
"nord-1": "#3b4252",
"nord-2": "#434c5e",
@@ -148,7 +148,52 @@
"nord-12": "#d08770",
"nord-13": "#ebcb8b",
"nord-14": "#a3be8c",
"nord-15": "#b48ead"
"nord-15": "#b48ead",
"red-800": "#693237",
"red-600": "#aa3e47",
"red-500": "#e63b49",
"red-400": "#f87171",
"red-200": "#fecaca",
"red-950": "#392b31",
"red-100": "#fee2e2",
"red-900": "#4c2d32",
"red-700": "#81383f",
"red-300": "#fca5a5",
"red-50": "#fef2f2",
"green-50": "#f0fdf4",
"green-100": "#dcfce7",
"green-200": "#bbf7d0",
"green-300": "#96f2b7",
"green-400": "#62e993",
"green-500": "#32c76d",
"green-600": "#319e69",
"green-700": "#3b7a5b",
"green-800": "#3b6054",
"green-900": "#284945",
"green-950": "#263b3d",
"orange-50": "#fff7ed",
"orange-100": "#ffedd5",
"orange-200": "#fed7aa",
"orange-300": "#fdba74",
"orange-400": "#fb923c",
"orange-500": "#f0721b",
"orange-600": "#cd6230",
"orange-700": "#905035",
"orange-800": "#654338",
"orange-900": "#4b3531",
"orange-950": "#3c2c2ddb",
"purple-50": "#faf5ff",
"purple-100": "#f3e8ff",
"purple-200": "#e5cdff",
"purple-300": "#cfa5fc",
"purple-400": "#b267fd",
"purple-500": "#9939f5",
"purple-600": "#8143ba",
"purple-700": "#5f407d",
"purple-800": "#483c60",
"purple-900": "#3a3549",
"purple-950": "#31313f",
"blue-950": "#213263"
}
},
"guidelines": { "mode-1": { "blue": "#5e81ac", "demo-background": "#ffffff00" } },
@@ -134,7 +134,7 @@
<div class="text-primary font-md font-semibold"> Script or flow to run on /windmill command </div>
<div class="relative">
{#if !teamName || (!$enterpriseLicense && platform === 'teams')}
<div class="absolute top-0 right-0 bottom-0 left-0 bg-surface-disabled/20 z-40"></div>
<div class="absolute top-0 right-0 bottom-0 left-0 bg-surface-disabled z-40"></div>
{/if}
<ScriptPicker
kinds={['script']}
@@ -162,7 +162,7 @@
<div class="flex flex-col gap-2">
<div class="flex gap-2 flex-wrap sticky top-0 left-0 right-0 bg-surface">
<div class="p-2">
<ToggleButtonGroup bind:selected={searchKind} class="h-10 ">
<ToggleButtonGroup bind:selected={searchKind}>
{#snippet children({ item })}
<ToggleButton small value="all" label={'All' + counts.all} {item} />
<ToggleButton
@@ -251,12 +251,8 @@
{#snippet actions()}
<Button
href={`/scripts/get/${item.path}`}
color="light"
size="xs"
startIcon={{ icon: ExternalLink }}
on:click={() => {
dispatch('close')
}}
on:click={() => dispatch('close')}
>
Open
</Button>
@@ -264,8 +260,6 @@
<Button
href={`/scripts/edit/${item.path}?no_draft=true`}
target="_blank"
color="light"
size="xs"
startIcon={{ icon: Edit }}
>
Edit
@@ -279,13 +273,8 @@
{#if filteredScriptItems.length > showNbScripts}
<Button
color="light"
size="xs"
on:click={() => {
showNbScripts += 30
}}
startIcon={{
icon: ArrowDown
}}
on:click={() => (showNbScripts += 30)}
startIcon={{ icon: ArrowDown }}
>
Show more scripts ({showNbScripts} of {filteredScriptItems.length})
</Button>
@@ -299,13 +288,7 @@
on:close
>
{#snippet actions()}
<Button
href={`/resources#${item.path}`}
color="light"
target="_blank"
size="xs"
startIcon={{ icon: Edit }}
>
<Button href={`/resources#${item.path}`} target="_blank" startIcon={{ icon: Edit }}>
Edit
</Button>
{/snippet}
@@ -318,12 +301,8 @@
<Button
color="light"
size="xs"
on:click={() => {
showNbResources += 30
}}
startIcon={{
icon: ArrowDown
}}
on:click={() => (showNbResources += 30)}
startIcon={{ icon: ArrowDown }}
>
Show more resources ({showNbResources} of {filteredResourceItems.length})
</Button>
@@ -339,20 +318,14 @@
{#snippet actions()}
<Button
href={`/flows/get/${item.path}`}
color="light"
size="xs"
startIcon={{ icon: ExternalLink }}
on:click={() => {
dispatch('close')
}}
on:click={() => dispatch('close')}
>
Open
</Button>
<Button
href={`/flows/edit/${item.path}?no_draft=true`}
color="light"
target="_blank"
size="xs"
startIcon={{ icon: Edit }}
>
Edit
@@ -368,12 +341,8 @@
<Button
color="light"
size="xs"
on:click={() => {
showNbFlows += 30
}}
startIcon={{
icon: ArrowDown
}}
on:click={() => (showNbFlows += 30)}
startIcon={{ icon: ArrowDown }}
>
Show more flows ({showNbFlows} of {filteredFlowItems.length})
</Button>
@@ -389,20 +358,14 @@
{#snippet actions()}
<Button
href={`/apps/get/${item.path}`}
color="light"
size="xs"
startIcon={{ icon: ExternalLink }}
on:click={() => {
dispatch('close')
}}
on:click={() => dispatch('close')}
>
Open
</Button>
<Button
href={`/apps/edit/${item.path}?no_draft=true`}
color="light"
target="_blank"
size="xs"
startIcon={{ icon: Edit }}
>
Edit
@@ -418,12 +381,8 @@
<Button
color="light"
size="xs"
on:click={() => {
showNbApps += 30
}}
startIcon={{
icon: ArrowDown
}}
on:click={() => (showNbApps += 30)}
startIcon={{ icon: ArrowDown }}
>
Show more apps ({showNbApps} of {filteredAppItems.length})
</Button>
@@ -16,7 +16,7 @@
<div class="flex flex-col gap-2">
<div class="flex flex-row items-center justify-between">
<a
class="text-sm text-blue-500 truncate hover:underline"
class="text-accent truncate text-xs"
{href}
onclick={() => {
dispatch('close')
+1 -1
View File
@@ -217,7 +217,7 @@
error={!validCRON}
/>
{#if !disabled}
<div class="flex flex-row gap-2">
<div class="flex flex-row gap-2 shrink-0">
{@render cronBuilder()}
<CronGen bind:schedule bind:cronVersion />
</div>
@@ -42,10 +42,12 @@
import ResultStreamDisplay from './ResultStreamDisplay.svelte'
import { twMerge } from 'tailwind-merge'
const IMG_MAX_SIZE = 10000000
const TABLE_MAX_SIZE = 5000000
const DISPLAY_MAX_SIZE = 100000
const IMG_KINDS = ['png', 'svg', 'jpeg', 'gif']
const NO_SIZE_LIMIT_KINDS = [...IMG_KINDS, 'pdf', 'file', 'filename', 'html']
const dispatch = createEventDispatcher()
type ResultKind =
@@ -199,14 +201,6 @@
is_render_all =
keys.length == 1 && keys.includes('render_all') && Array.isArray(result['render_all'])
// Check if the result is an image
if (['png', 'svg', 'jpeg', 'html', 'gif'].includes(keys[0]) && keys.length == 1) {
// Check if the image is too large (10mb)
largeObject = roughSizeOfObject(result) > IMG_MAX_SIZE
return keys[0] as 'png' | 'svg' | 'jpeg' | 'html' | 'gif'
}
let size = roughSizeOfObject(result)
console.debug('size of object', size)
// Otherwise, check if the result is too large (10kb) for json
@@ -253,26 +247,20 @@
return keys[0] as 'table-row' | 'table-row-object' | 'table-col'
}
if (largeObject) {
return 'json'
}
if (keys.length != 0) {
if (keys.length == 1 && keys[0] === 'html') {
return 'html'
} else if (keys.length == 1 && keys[0] === 'map') {
return 'map'
} else if (keys.length == 1 && keys[0] === 'pdf') {
return 'pdf'
} else if (keys.length == 1 && keys[0] === 'file') {
return 'file'
if (
keys.length == 1 &&
[...IMG_KINDS, 'html', 'map', 'pdf', 'file', 'error'].includes(keys[0])
) {
return !largeObject || NO_SIZE_LIMIT_KINDS.includes(keys[0])
? (keys[0] as ResultKind)
: 'json'
} else if (
!largeObject &&
keys.includes('windmill_content_type') &&
result['windmill_content_type'].startsWith('text/')
) {
return 'plain'
} else if (keys.length == 1 && keys[0] === 'error') {
return 'error'
} else if (keys.length === 2 && keys.includes('file') && keys.includes('filename')) {
return 'file'
} else if (
@@ -290,39 +278,44 @@
}
return 'file'
} else if (
!largeObject &&
keys.includes('resume') &&
keys.includes('cancel') &&
keys.includes('approvalPage')
) {
return 'approval'
} else if (checkIfS3(result, keys)) {
} else if (!largeObject && checkIfS3(result, keys)) {
return 's3object'
} else if (keys.length === 1 && (keys.includes('md') || keys.includes('markdown'))) {
} else if (
!largeObject &&
keys.length === 1 &&
(keys[0] === 'md' || keys[0] === 'markdown')
) {
return 'markdown'
} else if (isTableCol(result, keys)) {
} else if (!largeObject && isTableCol(result, keys)) {
return 'table-col'
} else if (keys.length < 1000 && keys.includes('wm_renderer')) {
const renderer = result['wm_renderer']
if (typeof renderer === 'string') {
if (
[
'json',
'html',
'png',
'file',
'jpeg',
'gif',
'svg',
'filename',
's3object',
'plain',
'markdown',
'map',
'pdf'
].includes(renderer)
) {
return renderer as ResultKind
}
if (
typeof renderer === 'string' &&
(!largeObject || NO_SIZE_LIMIT_KINDS.includes(renderer)) &&
[
'json',
'html',
'png',
'file',
'jpeg',
'gif',
'svg',
'filename',
's3object',
'plain',
'markdown',
'map',
'pdf'
].includes(renderer)
) {
return renderer as ResultKind
}
}
}
@@ -125,7 +125,7 @@
description: aiDescription,
callback: () => buttonEl?.click()
}}
class={twMerge('w-full flex items-center justify-end', fixedHeight && 'h-8', classNames)}
class={twMerge('flex items-center justify-end', fixedHeight && 'h-8', classNames)}
use:melt={$trigger}
{disabled}
onclick={(e) => e.stopPropagation()}
+1 -1
View File
@@ -1033,7 +1033,7 @@ JsonNode ${windmillPathToCamelCaseName(path)} = JsonNode.Parse(await client.GetS
</div>
</div>
<div class="flex flex-row items-center gap-2">
<div class="flex flex-row items-center gap-2 whitespace-nowrap">
{@render right?.()}
{#if scriptPath && !noHistory}
<Button
@@ -345,7 +345,7 @@
{#if !handlerPath}
<Button
btnClasses="ml-4"
btnClasses="ml-4 whitespace-nowrap"
variant="default"
size="xs"
href={customScriptTemplate}
@@ -1,15 +1,24 @@
<script lang="ts">
import { HistoryIcon } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, untrack } from 'svelte'
import PopoverV2 from '$lib/components/meltComponents/Popover.svelte'
import HistoricInputs from './HistoricInputs.svelte'
import { workspaceStore } from '$lib/stores'
import { JobService } from '$lib/gen'
export let path: string
export let selected: string | undefined = undefined
export let selectInitial: boolean = false
export let loading: boolean = false
interface Props {
path: string
selected?: string | undefined
selectInitial?: boolean
loading?: boolean
}
let {
path,
selected = undefined,
selectInitial = false,
loading = $bindable(false)
}: Props = $props()
const dispatch = createEventDispatcher()
async function loadInitial() {
@@ -18,7 +27,6 @@
workspace: $workspaceStore!,
scriptPathExact: path,
jobKinds: ['flow', 'flowpreview'].join(','),
page: 1,
perPage: 1
})
if (jobs.length > 0) {
@@ -31,14 +39,16 @@
loading = false
}
$: $workspaceStore && loadInitial()
$effect(() => {
$workspaceStore && untrack(() => loadInitial())
})
</script>
<PopoverV2 closeButton={false}>
<svelte:fragment slot="trigger">
{#snippet trigger()}
<HistoryIcon size={14} />
</svelte:fragment>
<svelte:fragment slot="content">
{/snippet}
{#snippet content()}
<div class="p-2 h-[400px] overflow-hidden w-80 border shadow-sm">
<HistoricInputs
on:select={(e) => {
@@ -53,5 +63,5 @@
runnableType={'FlowPath'}
/>
</div>
</svelte:fragment>
{/snippet}
</PopoverV2>
@@ -22,7 +22,7 @@
folderName = $bindable(''),
initialPath = $bindable(undefined),
disabled = $bindable(undefined),
disableEditing = $bindable(undefined)
disableEditing = $bindable(undefined),
}: Props = $props()
async function loadFolders(): Promise<void> {
@@ -59,6 +59,7 @@
})
folderCreated = newFolderName
$userStore?.folders?.push(newFolderName)
folderName = newFolderName
loadFolders()
}
@@ -104,7 +104,7 @@
{#if keys.length > 0}
{#each keys as argName, index (argName)}
{#if (!filter || filter.includes(argName)) && Object.keys(schema.properties ?? {}).includes(argName)}
<ResizeTransitionWrapper class="mt-6 relative" innerClass="w-full" vertical>
<ResizeTransitionWrapper class="mt-6" innerClass="w-full" vertical>
<InputTransformForm
{previousModuleId}
bind:arg={args[argName]}
@@ -862,9 +862,10 @@
{:else if setting.fieldType == 'smtp_connect'}
<div class="flex flex-col gap-4 border rounded p-4">
{#if $values[setting.key]}
<div class="flex gap-4"
><input type="email" bind:value={to} placeholder="contact@windmill.dev" />
<div class="flex gap-4">
<input type="email" bind:value={to} placeholder="contact@windmill.dev" />
<Button
wrapperClasses="shrink-0"
disabled={to == ''}
on:click={async () => {
let smtp = $values[setting.key]
@@ -118,7 +118,7 @@
<ResizeTransitionWrapper
vertical
class={twMerge(
'flex gap-2 relative',
'flex gap-2',
animateArg === argName && 'animate-pulse ring-2 ring-offset-2 ring-blue-500 rounded'
)}
innerClass="w-full"
+6 -6
View File
@@ -137,10 +137,10 @@
}
function minJobTime(jobs: CompletedJob[]): Date {
let min: Date = new Date(jobs[0].started_at)
let min: Date = new Date(jobs[0].completed_at!)
for (const job of jobs) {
if (job.started_at != undefined) {
const date = new Date(job.started_at)
if (job.completed_at != undefined) {
const date = new Date(job.completed_at)
if (date < min) {
min = date
}
@@ -150,10 +150,10 @@
}
function maxJobTime(jobs: CompletedJob[]): Date {
let max: Date = new Date(jobs[0].started_at)
let max: Date = new Date(jobs[0].completed_at!)
for (const job of jobs) {
if (new Date(job.started_at) > max) {
max = new Date(job.started_at)
if (new Date(job.completed_at!) > max) {
max = new Date(job.completed_at!)
}
}
return max
+44 -29
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { Button } from '$lib/components/common'
import {
InputService,
@@ -10,7 +11,7 @@
import { userStore, workspaceStore } from '$lib/stores.js'
import { base } from '$lib/base'
import { classNames, displayDateOnly, sendUserToast } from '$lib/utils.js'
import { createEventDispatcher } from 'svelte'
import { createEventDispatcher, untrack } from 'svelte'
import { Pane, Splitpanes } from 'svelte-splitpanes'
import ObjectViewer from './propertyPicker/ObjectViewer.svelte'
import { ArrowLeftIcon, Edit, ExternalLink, X } from 'lucide-svelte'
@@ -21,37 +22,49 @@
import Skeleton from './common/skeleton/Skeleton.svelte'
import SaveInputsButton from './SaveInputsButton.svelte'
export let scriptHash: string | null = null
export let scriptPath: string | null = null
export let flowPath: string | null = null
export let canSaveInputs: boolean = true
// Are the current Inputs valid and able to be saved?
export let isValid: boolean
export let args: object
interface Props {
scriptHash?: string | null;
scriptPath?: string | null;
flowPath?: string | null;
canSaveInputs?: boolean;
// Are the current Inputs valid and able to be saved?
isValid: boolean;
args: object;
}
let {
scriptHash = null,
scriptPath = null,
flowPath = null,
canSaveInputs = true,
isValid,
args
}: Props = $props();
interface EditableInput extends Input {
isEditing?: boolean
isSaving?: boolean
}
let previousInputs: Input[] | undefined = undefined
let savedInputs: EditableInput[] | undefined = undefined
let selectedInput: Input | null
let jobs: Job[] = []
let loading: boolean = false
let previousInputs: Input[] | undefined = $state(undefined)
let savedInputs: EditableInput[] | undefined = $state(undefined)
let selectedInput = $state() as Input | null
let jobs: Job[] = $state([])
let loading: boolean = $state(false)
const dispatch = createEventDispatcher()
$: runnableId = scriptHash || scriptPath || flowPath || undefined
let runnableId = $derived(scriptHash || scriptPath || flowPath || undefined)
let runnableType: RunnableType | undefined = $derived(scriptHash
? 'ScriptHash'
: scriptPath
? 'ScriptPath'
: flowPath
? 'FlowPath'
: undefined)
let runnableType: RunnableType | undefined = undefined
$: runnableType = scriptHash
? 'ScriptHash'
: scriptPath
? 'ScriptPath'
: flowPath
? 'FlowPath'
: undefined
let hasAlreadyFailed = false
async function loadInputHistory() {
@@ -115,14 +128,16 @@
}
}
$: {
$effect(() => {
if ($workspaceStore && (scriptHash || scriptPath || flowPath)) {
untrack(() => {
loadInputHistory()
loadSavedInputs()
})
}
}
});
let previewArgs: any = undefined
let previewArgs: any = $state(undefined)
function selectArgs(selected_args: any) {
previewArgs = selected_args
@@ -197,7 +212,7 @@
`w-full flex items-center text-sm group justify-between gap-4 py-1.5 px-4 text-left border rounded-sm hover:bg-surface-hover transition-all`,
selectedInput === i ? 'border-blue-500 bg-blue-50 dark:bg-blue-900' : ''
)}
on:click={async () => {
onclick={async () => {
if (!i.isEditing) {
if (selectedInput === i) {
selectedInput = null
@@ -211,7 +226,7 @@
<div class="w-full h-full items-center justify-between flex gap-1 min-w-0">
{#if i.isEditing}
<form
on:submit={() => {
onsubmit={() => {
updateInput(i)
i.isEditing = false
i.isSaving = false
@@ -296,7 +311,7 @@
`w-full flex items-center justify-between gap-4 py-2 px-4 text-left border rounded-sm hover:bg-surface-hover transition-a`,
'border-orange-400'
)}
on:click={async () => {
onclick={async () => {
if (!$workspaceStore) {
return
}
@@ -364,7 +379,7 @@
`w-full flex items-center justify-between gap-4 py-2 px-4 text-left border rounded-sm hover:bg-surface-hover transition-a`,
selectedInput === i ? 'border-blue-500 bg-blue-50 dark:bg-blue-900' : ''
)}
on:click={async () => {
onclick={async () => {
if (selectedInput === i) {
selectedInput = null
} else {
@@ -278,8 +278,7 @@
class={twMerge(
typeof diff[argName] === 'object' &&
diff[argName].diff !== 'same' &&
'bg-red-300 dark:bg-red-800 rounded-md',
'relative'
'bg-red-300 dark:bg-red-800 rounded-md'
)}
innerClass="w-full"
>
@@ -1106,14 +1106,6 @@
}}
/>
</Label>
{#if script.schema && !disableAi && !customUi?.settingsPanel?.metadata?.disableAiFilling}
<div class="mt-3">
<AIFormSettings
bind:prompt={script.schema.prompt_for_ai as string | undefined}
type="script"
/>
</div>
{/if}
</div>
</Section>
{#if !customUi?.settingsPanel?.metadata?.languages || customUi?.settingsPanel?.metadata?.languages?.length > 1}
@@ -1205,6 +1197,15 @@
/>
</Section>
{/if}
{#if script.schema && !disableAi && !customUi?.settingsPanel?.metadata?.disableAiFilling}
<div class="mt-3">
<AIFormSettings
bind:prompt={script.schema.prompt_for_ai as string | undefined}
type="script"
/>
</div>
{/if}
</div>
</TabContent>
<TabContent value="runtime">
@@ -1219,7 +1220,7 @@
{/snippet}
<div class="flex flex-col gap-4">
<Label label="Max number of executions within the time window">
<div class="flex flex-row gap-2 max-w-sm">
<div class="flex flex-row gap-2 max-w-sm whitespace-nowrap">
<input
disabled={!$enterpriseLicense}
bind:value={script.concurrent_limit}
@@ -1273,9 +1274,7 @@
{/snippet}
<div class="flex flex-col gap-4">
<Label label="Debounce Delay in seconds. (if not set - disabled)">
<SecondsInput
bind:seconds={script.debounce_delay_s}
/>
<SecondsInput bind:seconds={script.debounce_delay_s} />
<Button
size="sm"
color="light"
@@ -1291,9 +1290,9 @@
<Tooltip
documentationLink="https://www.windmill.dev/docs/core_concepts/debouncing#custom-debounce-key"
>
Debounce Keys are global, you can have them be workspace specific
using the variable `$workspace`. You can also use an argument's value
using `$args[name_of_arg]`</Tooltip
Debounce Keys are global, you can have them be workspace specific using
the variable `$workspace`. You can also use an argument's value using
`$args[name_of_arg]`</Tooltip
>
{/snippet}
<input
+1 -1
View File
@@ -112,7 +112,7 @@
color == 'red'
? 'peer-checked:bg-red-600'
: color == 'blue'
? 'peer-checked:bg-luminance-blue-400 '
? 'peer-checked:bg-blue-400 '
: 'peer-checked:bg-nord-950 dark:peer-checked:bg-nord-900',
size === 'md'
? 'w-11 h-6 after:top-0.5 after:left-[2px] after:h-5 after:w-5'
@@ -7,7 +7,6 @@
import { createEventDispatcher } from 'svelte'
import UserInfoSettings from './settings/UserInfoSettings.svelte'
import AIUserSettings from './settings/AIUserSettings.svelte'
import UserAIPromptsSettings from './settings/UserAIPromptsSettings.svelte'
interface Props {
scopes?: string[] | undefined
@@ -70,7 +69,6 @@
</div>
<div class="min-w-0">
<AIUserSettings />
<UserAIPromptsSettings />
</div>
</div>
{/if}
@@ -179,13 +179,13 @@
({variable.value.length}/{MAX_VARIABLE_LENGTH} characters)
</span>
{#if edit && variable.is_secret}
<div class="ml-2"></div>
<div class="ml-3"></div>
{#if $userStore?.operator}
<div class="p-2 border">Operators cannot load secret value</div>
{:else}
<Button size="xs" variant="subtle" on:click={() => loadVariable(initialPath)}
>Load secret value<Tooltip>Will generate an audit log</Tooltip></Button
>
<Button size="xs" variant="default" on:click={() => loadVariable(initialPath)}>
Load secret value<Tooltip>Will generate an audit log</Tooltip>
</Button>
{/if}
{/if}
</label>
@@ -269,7 +269,7 @@
{/if}
{#key css}
<div
class="inline-flex"
class={twMerge('inline-flex', resolvedConfig.fillContainer ? 'w-full h-full' : '')}
title={resolvedConfig.tooltip && String(resolvedConfig.tooltip).length > 0
? String(resolvedConfig.tooltip)
: undefined}
@@ -1273,7 +1273,7 @@
<Dropdown items={moreItems} />
<AppEditorTutorial bind:this={appEditorTutorial} />
<div class="hidden md:inline relative overflow-visible">
<div class="hidden md:inline relative overflow-visible shrink-0">
{#if hasErrors}
<span
class="animate-ping absolute inline-flex rounded-full bg-red-600 h-2 w-2 z-50 -right-0.5 -top-0.5"
@@ -1296,7 +1296,7 @@
>
<div class="flex flex-row gap-1 items-center">
<div>Debug runs</div>
<div class="text-2xs text-primary"
<div class="text-2xs {hasErrors ? '' : 'text-primary'}"
>({$jobs?.length > 99 ? '99+' : ($jobs?.length ?? 0)})</div
>
{#if hasErrors}
@@ -83,7 +83,7 @@
/>
{:else}
<ThemeCodePreview theme={$app.theme}>
<div class="p-2 w-min">
<div class="p-2 w-min whitespace-nowrap">
<Button
size="xs"
color="dark"
@@ -62,7 +62,7 @@
{#if currentResizeTransitionWrapper}
{@render children()}
{:else}
<div bind:this={outerContainer} {...outerDivProps} class={className} {style}>
<div bind:this={outerContainer} {...outerDivProps} class={twMerge('relative', className)} {style}>
<div class={twMerge('absolute', innerClass)} bind:this={innerContainer}>
{@render children()}
</div>
@@ -2,11 +2,10 @@ export type AlertType = 'success' | 'error' | 'warning' | 'info'
export const classes: Record<AlertType, Record<string, string>> = {
info: {
bgClass:
'bg-luminance-blue-50 border-luminance-blue-100 border dark:bg-luminance-blue-900/60 dark:border-luminance-blue-700/40',
iconClass: 'text-luminance-blue-600 dark:text-luminance-blue-50',
titleClass: 'text-luminance-blue-700 dark:text-luminance-blue-50',
descriptionClass: 'text-luminance-blue-600 dark:text-luminance-blue-50/80'
bgClass: 'bg-blue-50 border-blue-100 border dark:bg-blue-900/60 dark:border-blue-700/40',
iconClass: 'text-blue-600 dark:text-blue-50',
titleClass: 'text-blue-700 dark:text-blue-50',
descriptionClass: 'text-blue-600 dark:text-blue-50/80'
},
warning: {
bgClass:
@@ -48,7 +48,7 @@
let hidden = $state(false)
const colors: Record<BadgeColor, string> = {
gray: 'bg-surface-sunken text-primary',
blue: 'bg-luminance-blue-50 text-luminance-blue-800 dark:text-luminance-blue-100 dark:bg-luminance-blue-700/40',
blue: 'bg-blue-50 text-blue-800 dark:text-blue-100 dark:bg-blue-700/40',
red: 'bg-red-100 text-red-800 dark:bg-red-700/40 dark:text-red-100',
green: 'bg-green-100 text-green-700 dark:bg-green-700/40 dark:text-green-100',
yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-700/40 dark:text-yellow-100',
@@ -68,7 +68,7 @@
const selectedColors: Record<BadgeColor, string> = {
gray: 'bg-surface-input text-primary',
blue: 'bg-luminance-blue-500 text-white dark:bg-luminance-blue-600',
blue: 'bg-blue-500 text-white dark:bg-blue-600',
red: 'bg-red-500 text-white dark:bg-red-600',
green: 'bg-green-500 text-white dark:bg-green-600',
yellow: 'bg-yellow-500 text-white dark:bg-yellow-600',
@@ -76,20 +76,19 @@
indigo: 'bg-indigo-500 text-white dark:bg-indigo-600',
violet: 'bg-violet-500 text-white dark:bg-violet-600',
['dark-gray']: 'bg-gray-700 text-gray-100 dark:bg-gray-800 dark:text-gray-200',
['dark-blue']:
'bg-luminance-blue-700 text-luminance-blue-100 dark:bg-luminance-blue-800 dark:text-luminance-blue-200',
['dark-blue']: 'bg-blue-700 text-blue-100 dark:bg-blue-800 dark:text-blue-200',
['dark-red']: 'bg-red-700 text-white dark:bg-red-800 dark:text-red-100',
['dark-green']: 'bg-green-700 text-green-100 dark:bg-green-800 dark:text-green-200',
['dark-yellow']: 'bg-yellow-600 text-white dark:bg-yellow-700 dark:text-yellow-100',
['dark-indigo']: 'bg-indigo-700 text-indigo-100 dark:bg-indigo-800 dark:text-indigo-200',
['dark-orange']: 'bg-orange-700 text-orange-100 dark:bg-orange-800 dark:text-orange-200',
['dark-violet']: 'bg-violet-700 text-violet-100 dark:bg-violet-800 dark:text-violet-200',
transparent: 'bg-surface-accent-selected/30 text-accent border-gray-400 dark:border-gray-500'
transparent: 'bg-surface-accent-selected text-accent border-gray-400 dark:border-gray-500'
}
const hovers: Partial<Record<BadgeColor, string>> = {
gray: 'hover:bg-surface-hover',
blue: 'hover:bg-luminance-blue-200 dark:hover:bg-luminance-blue-700/40',
blue: 'hover:bg-blue-200 dark:hover:bg-blue-700/40',
red: 'hover:bg-red-200 dark:hover:bg-red-500/25',
green: 'hover:bg-green-200 dark:hover:bg-green-500/25',
yellow: 'hover:bg-yellow-200 dark:hover:bg-yellow-500/25',
@@ -97,7 +96,7 @@
orange: 'hover:bg-orange-200 dark:hover:bg-orange-500/25',
violet: 'hover:bg-violet-200 dark:hover:bg-violet-500/25',
['dark-gray']: 'hover:bg-gray-600 dark:hover:bg-gray-700',
['dark-blue']: 'hover:bg-luminance-blue-600 dark:hover:bg-luminance-blue-700',
['dark-blue']: 'hover:bg-blue-600 dark:hover:bg-blue-700',
['dark-red']: 'hover:bg-red-600 dark:hover:bg-red-700',
['dark-green']: 'hover:bg-green-600 dark:hover:bg-green-700',
['dark-yellow']: 'hover:bg-yellow-600 dark:hover:bg-yellow-700',
@@ -194,7 +194,7 @@
const horizontalPadding = iconOnly
? ButtonType.UnifiedIconOnlySizingClasses[unifiedSize]
: ButtonType.UnifiedSizingClasses[unifiedSize]
const height = ButtonType.UnifiedHeightClasses[unifiedSize]
const height = ButtonType.UnifiedMinHeightClasses[unifiedSize]
return `${horizontalPadding} ${height}`
}
@@ -215,7 +215,7 @@
if (variant === 'default') {
return 'border border-border-light divide-x divide-border-light'
} else if (variant === 'accent') {
return 'divide-x divide-luminance-blue-100 dark:divide-luminance-blue-200'
return 'divide-x divide-blue-100 dark:divide-blue-200'
} else if (variant === 'accent-secondary') {
return 'divide-x divide-deep-blue-400 dark:divide-deep-blue-100'
} else if (variant === 'subtle') {
@@ -242,16 +242,16 @@
unifiedSize ? ButtonType.UnifiedFontSizes[unifiedSize] : '',
'focus-visible:ring-2',
dropdownItems && dropdownItems.length > 0 ? 'rounded-l-md' : 'rounded-md',
'justify-center items-center text-center whitespace-nowrap inline-flex gap-2',
'justify-center items-center text-center inline-flex gap-2',
'active:opacity-80 transition-[background-color,opacity] duration-150',
disabled
? ['default', 'subtle'].includes(variant)
? '!text-disabled'
: '!bg-surface-disabled/20 !text-disabled'
: '!bg-surface-disabled !text-disabled'
: '',
loading ? 'cursor-wait' : '',
selected && ['default', 'subtle'].includes(variant)
? '!bg-surface-accent-selected/30 !text-accent !border-border-selected'
? '!bg-surface-accent-selected !text-accent !border-border-selected'
: '',
btnClasses
)
@@ -114,10 +114,10 @@ export namespace ButtonType {
blue: {
border:
'border-luminance-blue-500 dark:border-luminance-blue-300 hover:border-luminance-blue-700 focus-visible:border-luminance-blue-700 bg-surface hover:bg-luminance-blue-100 dark:hover:bg-luminance-blue-900/40 focus-visible:bg-luminance-blue-100 focus-visible:dark:text-luminance-blue-100 dark:focus-visible:bg-luminance-blue-900 text-luminance-blue-500 dark:text-luminance-blue-300 dark:hover:text-luminance-blue-200 hover:text-luminance-blue-700 focus-visible:text-luminance-blue-700 focus-visible:ring-luminance-blue-300',
'border-blue-500 dark:border-blue-300 hover:border-blue-700 focus-visible:border-blue-700 bg-surface hover:bg-blue-100 dark:hover:bg-blue-900/40 focus-visible:bg-blue-100 focus-visible:dark:text-blue-100 dark:focus-visible:bg-blue-900 text-blue-500 dark:text-blue-300 dark:hover:text-blue-200 hover:text-blue-700 focus-visible:text-blue-700 focus-visible:ring-blue-300',
contained:
'bg-luminance-blue-300 hover:bg-luminance-blue-400 focus-visible:bg-luminance-blue-500 text-white focus-visible:ring-luminance-blue-300',
divider: 'divide-x divide-luminance-blue-600'
'bg-blue-300 hover:bg-blue-400 focus-visible:bg-blue-500 text-white focus-visible:ring-blue-300',
divider: 'divide-x divide-blue-600'
},
marine: {
border:
@@ -173,13 +173,13 @@ export namespace ButtonType {
export const VariantStyles: Record<'accent-secondary' | 'accent' | 'default' | 'subtle', string> =
{
'accent-secondary':
'bg-surface-accent-secondary hover:bg-surface-accent-secondary-hover focus-visible:bg-surface-accent-secondary-clicked text-white dark:text-deep-blue-900 focus-visible:ring-luminance-blue-300',
'bg-surface-accent-secondary hover:bg-surface-accent-secondary-hover focus-visible:bg-surface-accent-secondary-clicked text-white dark:text-deep-blue-900 focus-visible:ring-blue-300',
accent:
'bg-surface-accent-primary hover:bg-surface-accent-hover focus-visible:bg-surface-accent-clicked text-white focus-visible:ring-luminance-blue-300',
'bg-surface-accent-primary hover:bg-surface-accent-hover focus-visible:bg-surface-accent-clicked text-white focus-visible:ring-blue-300',
default:
'border border-border-light bg-transparent hover:bg-surface-hover text-primary focus-visible:bg-surface-hover focus-visible:ring-luminance-blue-300',
'border border-border-light bg-transparent hover:bg-surface-hover text-primary focus-visible:bg-surface-hover focus-visible:ring-blue-300',
subtle:
'bg-transparent hover:bg-surface-hover text-primary focus-visible:bg-surface-hover focus-visible:ring-luminance-blue-300'
'bg-transparent hover:bg-surface-hover text-primary focus-visible:bg-surface-hover focus-visible:ring-blue-300'
}
export const DestructiveVariantStyles: Record<
@@ -69,7 +69,7 @@
Icon: RefreshCcw,
color: 'dark',
classes: {
icon: 'text-blue-500 dark:text-blue-400',
icon: 'text-blue-700 dark:text-blue-300',
iconWrapper: 'bg-blue-100 dark:bg-blue-800/50'
}
}
@@ -2,6 +2,7 @@
import { Button } from '$lib/components/common'
import { WandSparkles } from 'lucide-svelte'
import { aiChatManager } from './chat/AIChatManager.svelte'
import { flowAIBtnClasses } from './chat/flow/FlowAIButton.svelte'
interface Props {
label?: string
initialInput?: string
@@ -27,8 +28,8 @@
startIcon={{
icon: WandSparkles
}}
size="xs2"
btnClasses="!text-ai border border-gray-200 dark:border-gray-600 !bg-surface"
unifiedSize="md"
btnClasses={flowAIBtnClasses('default')}
on:click={onClick}
>
{label}
@@ -262,15 +262,15 @@ Generate a tool name for the script below:
}}
>
<div
class="absolute left-[0.5rem] {elementType === 'textarea'
class="absolute left-3 {elementType === 'textarea'
? 'top-[1.3rem]'
: 'top-[0.3rem]'} flex flex-row gap-2 items-start pointer-events-none"
>
{#if active}
<span
class={twMerge(
'rounded-md px-1 border',
flowAIBtnClasses(!loading && generatedContent.length > 0 ? 'green' : 'default')
'rounded-md px-1',
flowAIBtnClasses(!loading && generatedContent.length > 0 ? 'green' : 'selected')
)}
>
<span class="px-0.5 py-0.5 rounded-md text-2xs text-bold flex flex-row items-center gap-1">
@@ -291,7 +291,7 @@ Generate a tool name for the script below:
<div
bind:clientHeight={genHeight}
class={twMerge(
'text-sm leading-6 indent-[3.5rem] text-gray-500 dark:text-gray-400 pr-1',
'text-sm leading-6 indent-0 text-gray-500 dark:text-gray-400 pr-1',
elementType === 'input' ? 'text-ellipsis overflow-hidden whitespace-nowrap' : ''
)}
style={elementType === 'input' ? `max-width: calc(${width}px - 0.5rem)` : ''}
@@ -112,7 +112,7 @@
<Button
{...btn.buttonProps}
startIcon={{ icon: btn.buttonProps.startIcon }}
btnClasses="hidden md:flex items-center gap-1"
btnClasses="hidden md:flex items-center gap-1 whitespace-nowrap"
>
{btn.label}
</Button>
@@ -120,7 +120,7 @@
{...btn.buttonProps}
startIcon={{ icon: btn.buttonProps.startIcon }}
iconOnly
btnClasses="flex md:hidden items-center gap-1"
btnClasses="flex md:hidden items-center gap-1 whitespace-nowrap"
>
{btn.label}
</Button>
@@ -692,7 +692,7 @@
{/snippet}
{#if flowModule.value.type == 'rawscript'}
<Label label="Max number of executions within the time window">
<div class="flex flex-row gap-2 max-w-sm">
<div class="flex flex-row gap-2 max-w-sm whitespace-nowrap">
<input
disabled={!$enterpriseLicense}
bind:value={flowModule.value.concurrent_limit}
@@ -33,16 +33,15 @@
const dispatch = createEventDispatcher()
let customUi: undefined | FlowBuilderWhitelabelCustomUi = getContext('customUi')
let popoverClasses =
'center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600'
</script>
<div class="flex flex-row space-x-1">
<div class="flex flex-row space-x-1 whitespace-nowrap">
{#if module.value.type === 'script' || module.value.type === 'rawscript' || module.value.type == 'flow'}
{#if module.retry?.constant || module.retry?.exponential}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
onClick={() => dispatch('toggleRetry')}
>
<Popover placement="bottom" class={popoverClasses} onClick={() => dispatch('toggleRetry')}>
<Repeat size={14} />
{#snippet text()}
Retries
@@ -52,7 +51,7 @@
{#if module?.value?.['concurrent_limit'] != undefined}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
class={popoverClasses}
onClick={() => dispatch('toggleConcurrency')}
>
<Gauge size={14} />
@@ -62,11 +61,7 @@
</Popover>
{/if}
{#if module.cache_ttl != undefined}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
onClick={() => dispatch('toggleCache')}
>
<Popover placement="bottom" class={popoverClasses} onClick={() => dispatch('toggleCache')}>
<Database size={14} />
{#snippet text()}
Cache
@@ -76,7 +71,7 @@
{#if module.stop_after_if || module.stop_after_all_iters_if}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
class={popoverClasses}
onClick={() => dispatch('toggleStopAfterIf')}
>
<Square size={14} />
@@ -86,11 +81,7 @@
</Popover>
{/if}
{#if module.suspend}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
onClick={() => dispatch('toggleSuspend')}
>
<Popover placement="bottom" class={popoverClasses} onClick={() => dispatch('toggleSuspend')}>
<PhoneIncoming size={14} />
{#snippet text()}
Suspend
@@ -98,11 +89,7 @@
</Popover>
{/if}
{#if module.sleep}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
onClick={() => dispatch('toggleSleep')}
>
<Popover placement="bottom" class={popoverClasses} onClick={() => dispatch('toggleSleep')}>
<Bed size={14} />
{#snippet text()}
Sleep
@@ -110,11 +97,7 @@
</Popover>
{/if}
{#if module.mock?.enabled}
<Popover
placement="bottom"
class="center-center rounded p-2 bg-blue-100 text-blue-800 border border-blue-300 hover:bg-blue-200 dark:bg-frost-700 dark:text-frost-100 dark:border-frost-600"
onClick={() => dispatch('togglePin')}
>
<Popover placement="bottom" class={popoverClasses} onClick={() => dispatch('togglePin')}>
<Pin size={14} />
{#snippet text()}
This step is pinned
@@ -92,7 +92,7 @@
<JsonEditor {code} on:changeValue={updateMockValue} />
{/key}
{:else}
<pre class="text-xs border rounded p-2 bg-surface-disabled/20"
<pre class="text-xs border rounded p-2 bg-surface-disabled"
>{flowModule.mock?.return_value
? JSON.stringify(flowModule.mock?.return_value, null, 2)
: ''}</pre
@@ -77,7 +77,7 @@
right: 'Add a custom timeout for this step'
}}
/>
<Label label="Timeout duration">
<Label label="Timeout duration" class="mt-2">
{#if flowModule.timeout && schema.properties['timeout']}
<div class="border">
<PropPickerWrapper
@@ -427,7 +427,7 @@
{#if flowStore.val.value.concurrent_limit}
<div class="flex flex-col gap-6 mt-6" transition:slide={{ duration: 120 }}>
<Label label="Max number of executions within the time window">
<div class="flex flex-row gap-2 max-w-sm">
<div class="flex flex-row gap-2 max-w-sm whitespace-nowrap">
<input
disabled={!$enterpriseLicense}
bind:value={flowStore.val.value.concurrent_limit}
@@ -492,7 +492,8 @@
}}
options={{
right: 'Debounce limits',
rightTooltip: 'Consolidate multiple flow executions into a single run within a time window',
rightTooltip:
'Consolidate multiple flow executions into a single run within a time window',
rightDocumentationLink: 'https://www.windmill.dev/docs/core_concepts/debouncing'
}}
class="py-1"
@@ -130,6 +130,7 @@
<Button
variant="accent-secondary"
wrapperClasses="whitespace-nowrap"
unifiedSize="md"
on:click={() => {
previewMode = 'whole'
@@ -327,7 +327,7 @@
loadingJobs: true
}
}
const previousJobId = await JobService.listJobs({
const previousJobId = await JobService.listCompletedJobs({
workspace: $workspaceStore!,
scriptPathExact: path,
jobKinds: ['preview', 'script', 'flowpreview', 'flow'].join(','),
@@ -305,9 +305,7 @@
href={undefined}
class={twMerge(
'text-xs',
data.asset.kind === 'resource'
? 'text-blue-400 cursor-pointer'
: 'dark:text-primary text-primary-inverse'
data.asset.kind === 'resource' ? 'text-accent cursor-pointer' : 'text-hint'
)}
onclick={() => {
if (data.asset.kind === 'resource')
@@ -316,8 +314,8 @@
>
{data.asset.path}
</a><br />
<span class="dark:text-primary text-primary-inverse text-xs"
>{formatAssetKind({ ...data.asset, metadata: cachedResourceMetadata })}</span
<span class="text-hint text-xs">
{formatAssetKind({ ...data.asset, metadata: cachedResourceMetadata })}</span
>
</svelte:fragment>
</Tooltip>
+10 -10
View File
@@ -22,7 +22,7 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
let defaultStyle = {
selected: {
bg: 'bg-surface-accent-selected/30',
bg: 'bg-surface-accent-selected',
outline: 'outline-border-selected' + outlined,
text: 'text-accent',
badge: 'bg-blue-100 outline-border-selected text-blue-800'
@@ -36,13 +36,13 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
} satisfies Record<any, FlowNodeColorClasses>
let orangeStyle = {
selected: {
bg: 'bg-orange-200 dark:bg-[#905036]',
bg: 'bg-orange-200 dark:bg-orange-700',
outline: 'outline-orange-500' + outlined,
text: 'text-orange-800 dark:text-orange-200',
badge: 'bg-orange-100 text-orange-700'
},
notSelected: {
bg: 'bg-orange-100 dark:bg-[#654338]',
bg: 'bg-orange-100 dark:bg-orange-800',
outline: '',
text: 'text-orange-700 dark:text-orange-300',
badge: 'bg-orange-200 text-orange-700'
@@ -60,7 +60,7 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
_Skipped: {
selected: defaultStyle.selected,
notSelected: {
bg: 'bg-blue-100 dark:bg-[#2D3B63]',
bg: 'bg-blue-100 dark:bg-blue-950',
outline: '',
text: 'text-blue-600 dark:text-blue-200',
badge: 'bg-blue-200 outline-border-selected text-blue-800'
@@ -68,13 +68,13 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
},
Success: {
selected: {
bg: 'bg-green-200 dark:bg-[#329E6A]',
bg: 'bg-green-200 dark:bg-green-600',
outline: 'outline-green-500 dark:outline-green-400' + outlined,
text: 'text-green-800 dark:text-green-100',
badge: 'bg-green-100 text-green-700'
},
notSelected: {
bg: 'bg-green-100 dark:bg-[#3B7B5B]',
bg: 'bg-green-100 dark:bg-green-700',
outline: '',
text: 'text-green-700 dark:text-green-100',
badge: 'bg-green-200 text-green-700'
@@ -82,13 +82,13 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
},
Failure: {
selected: {
bg: 'bg-red-200 dark:bg-[#AA3E47]',
bg: 'bg-red-200 dark:bg-red-600',
outline: 'outline-red-500' + outlined,
text: 'text-red-800 dark:text-red-100',
badge: 'bg-red-100 text-red-700'
},
notSelected: {
bg: 'bg-red-100 dark:bg-[#81383F]',
bg: 'bg-red-100 dark:bg-red-700',
outline: '',
text: 'text-red-700 dark:text-red-200',
badge: 'bg-red-200 text-red-700'
@@ -98,13 +98,13 @@ export function getNodeColorClasses(state: FlowNodeState, selected: boolean): Fl
WaitingForExecutor: orangeStyle,
WaitingForEvents: {
selected: {
bg: 'bg-purple-200 dark:bg-[#8243BB]',
bg: 'bg-purple-200 dark:bg-purple-600',
outline: 'outline-purple-500' + outlined,
text: 'text-purple-800 dark:text-purple-100',
badge: 'bg-purple-100 text-purple-700'
},
notSelected: {
bg: 'bg-purple-100 dark:bg-[#5F417E]',
bg: 'bg-purple-100 dark:bg-purple-700',
outline: '',
text: 'text-purple-700 dark:text-purple-200',
badge: 'bg-purple-200 text-purple-700'
@@ -29,6 +29,8 @@
import Toggle from '../Toggle.svelte'
import { TriangleAlert } from 'lucide-svelte'
import { readFieldsRecursively } from '$lib/utils'
import Button from '../common/button/Button.svelte'
import ResizeTransitionWrapper from '../common/ResizeTransitionWrapper.svelte'
let {
selectedIds,
@@ -158,7 +160,7 @@
<div class="flex-1 flex flex-col">
<p class="ml-4 mt-4 text-xs font-semibold truncate">Batch re-run options</p>
<div class="border m-4 flex-1">
<div class="border overflow-auto rounded-md m-4 flex-1">
<Splitpanes>
<Pane size={32} class="bg-surface-secondary relative">
<PanelSection
@@ -169,16 +171,17 @@
<div class="w-full flex flex-col gap-1">
{#await jobGroupsPromise then jobGroup}
{#each jobGroup as group}
<button
class="border rounded-sm w-full text-left font-normal py-1.5 px-2 text-2xs flex justify-between {selected?.kind ===
group.kind && selected.script_path === group.script_path
? 'border-blue-500 bg-blue-100 dark:bg-frost-900/50'
: 'hover:bg-blue-50 dark:hover:bg-frost-900/50'}"
onclick={() => (selected = group)}
<Button
variant="default"
unifiedSize="sm"
selected={selected?.kind === group.kind &&
selected.script_path === group.script_path}
onClick={() => (selected = group)}
btnClasses="flex"
>
<span class="truncate"> {group.script_path}</span>
<span class="text-gray-400">({jobGroupTotalCount(group)})</span>
</button>
<span class="truncate flex-1 text-left"> {group.script_path}</span>
<span class="text-hint">({jobGroupTotalCount(group)})</span>
</Button>
{/each}
{/await}
</div>
@@ -226,48 +229,50 @@
<div class="w-full h-full">
{#key [selected, displayedSchema]}
{#each Object.keys(displayedSchema.properties) as propertyName}
<InputTransformForm
class="items-start mb-4"
arg={options[selected.kind][selected.script_path]?.input_transforms?.[
propertyName
] ?? {
type: 'javascript',
expr: batchReRunDefaultPropertyExpr(propertyName, selected.schemas)
}}
on:change={(e) => {
if (!selected) return
const newArg = e.detail.arg as InputTransform
;((options[selected.kind][selected.script_path] ??= {}).input_transforms ??=
{})[propertyName] = newArg
}}
argName={propertyName}
schema={displayedSchema}
{extraLib}
previousModuleId={undefined}
pickableProperties={{
hasResume: false,
previousId: undefined,
priorIds: {},
flow_input: {}
}}
hideHelpButton
{...propertyAlwaysExists(propertyName, selected)
? {}
: {
headerTooltip:
'This property does not exist on all versions of the script. You can handle different cases in the code below',
HeaderTooltipIcon: TriangleAlert,
headerTooltipIconClass: 'text-orange-500'
}}
{...propertyAlwaysHasSameType(propertyName, selected)
? {}
: {
headerTooltip:
'This property does not always have the same type depending on the version of the script. You can handle different cases in the code below',
HeaderTooltipIcon: TriangleAlert,
headerTooltipIconClass: 'text-orange-500'
}}
/>
<ResizeTransitionWrapper vertical innerClass="w-full">
<InputTransformForm
class="items-start mb-6"
arg={options[selected.kind][selected.script_path]?.input_transforms?.[
propertyName
] ?? {
type: 'javascript',
expr: batchReRunDefaultPropertyExpr(propertyName, selected.schemas)
}}
on:change={(e) => {
if (!selected) return
const newArg = e.detail.arg as InputTransform
;((options[selected.kind][selected.script_path] ??= {}).input_transforms ??=
{})[propertyName] = newArg
}}
argName={propertyName}
schema={displayedSchema}
{extraLib}
previousModuleId={undefined}
pickableProperties={{
hasResume: false,
previousId: undefined,
priorIds: {},
flow_input: {}
}}
hideHelpButton
{...propertyAlwaysExists(propertyName, selected)
? {}
: {
headerTooltip:
'This property does not exist on all versions of the script. You can handle different cases in the code below',
HeaderTooltipIcon: TriangleAlert,
headerTooltipIconClass: 'text-orange-500'
}}
{...propertyAlwaysHasSameType(propertyName, selected)
? {}
: {
headerTooltip:
'This property does not always have the same type depending on the version of the script. You can handle different cases in the code below',
HeaderTooltipIcon: TriangleAlert,
headerTooltipIconClass: 'text-orange-500'
}}
/>
</ResizeTransitionWrapper>
{/each}
{/key}
</div>
@@ -6,7 +6,10 @@
type CompletedJob,
type ExtendedJobs,
ConcurrencyGroupsService,
type ObscuredJob
type ObscuredJob,
} from '$lib/gen'
import { sendUserToast } from '$lib/toast'
@@ -136,11 +139,32 @@
export async function loadExtraJobs(): Promise<boolean> {
if (jobs && jobs.length > 0) {
const lastJob = jobs[jobs.length - 1]
// const minCreated = lastJob?.created_at
const minCreated = new Date(new Date(lastJob.created_at!).getTime() - 1).toISOString()
let minQueueTs: string | undefined = undefined
let minCompletedTs: string | undefined = undefined
let olderJobs = await fetchJobs(undefined, minTs, undefined, minCreated)
let cursor = 0
while (jobs && cursor < jobs?.length) {
cursor++
const job = jobs[jobs.length - 1 - cursor]
if (job.type == 'CompletedJob') {
minCompletedTs = job.completed_at
break
} else if (job.type == 'QueuedJob' && minQueueTs == undefined) {
minQueueTs = job.created_at
}
}
const ts = minCompletedTs ?? minQueueTs
if (!ts) {
sendUserToast("No jobs to load from")
return false
}
// const minCreated = lastJob?.created_at
const minCreated = new Date(new Date(ts).getTime() - 1).toISOString()
let olderJobs = await fetchJobs(minCreated, minTs, undefined)
jobs = jobs.concat(olderJobs)
computeCompletedJobs()
return olderJobs?.length < 1000
@@ -149,10 +173,9 @@
}
async function fetchJobs(
startedBefore: string | undefined,
startedAfter: string | undefined,
startedAfterCompletedJobs: string | undefined,
createdBefore: string | undefined
completedBefore: string | undefined,
completedAfter: string | undefined,
createdAfterQueue: string | undefined
): Promise<Job[]> {
loadingFetch = true
try {
@@ -160,12 +183,11 @@
let scriptPathExact = path === null || path === '' ? undefined : path
return JobService.listJobs({
workspace: $workspaceStore!,
createdOrStartedBefore: startedBefore,
createdOrStartedAfter: startedAfter,
createdOrStartedAfterCompletedJobs: startedAfterCompletedJobs,
completedBefore,
completedAfter,
createdAfterQueue,
schedulePath,
scriptPathExact,
createdBefore,
createdBy: user === null || user === '' ? undefined : user,
scriptPathStart: scriptPathStart,
jobKinds: jobKindsCat == 'all' || jobKinds == '' ? undefined : jobKinds,
@@ -211,9 +233,8 @@
async function fetchExtendedJobs(
concurrencyKey: string | null,
startedBefore: string | undefined,
startedAfter: string | undefined,
startedAfterCompletedJobs: string | undefined
createdBeforeQueue: string | undefined,
completedAfter: string | undefined
): Promise<ExtendedJobs> {
loadingFetch = true
try {
@@ -221,9 +242,11 @@
rowLimit: 1000,
concurrencyKey: concurrencyKey == null || concurrencyKey == '' ? undefined : concurrencyKey,
workspace: $workspaceStore!,
createdOrStartedBefore: startedBefore,
createdOrStartedAfter: startedAfter,
createdOrStartedAfterCompletedJobs: startedAfterCompletedJobs,
completedAfter,
createdBeforeQueue: createdBeforeQueue,
// createdOrStartedBefore: startedBefore,
// createdOrStartedAfter: startedAfter,
// createdOrStartedAfterCompletedJobs: startedAfterCompletedJobs,
schedulePath,
scriptPathExact: path === null || path === '' ? undefined : path,
createdBy: user === null || user === '' ? undefined : user,
@@ -294,7 +317,7 @@
// lookback won't be needed anymore (just filter ended_at > minTs instead
const extendedMinTs = subtractDaysFromDateString(minTs, lookback)
if (concurrencyKey == null || concurrencyKey === '') {
let newJobs = await fetchJobs(maxTs, undefined, extendedMinTs, undefined)
let newJobs = await fetchJobs(maxTs, undefined, extendedMinTs)
extendedJobs = { jobs: newJobs, obscured_jobs: [] } as ExtendedJobs
// Filter on minTs here and not in the backend
@@ -302,7 +325,7 @@
jobs = sortMinDate(minTs, newJobs)
externalJobs = []
} else {
extendedJobs = await fetchExtendedJobs(concurrencyKey, maxTs, undefined, extendedMinTs)
extendedJobs = await fetchExtendedJobs(concurrencyKey, maxTs, extendedMinTs)
const newJobs = extendedJobs.jobs
const newExternalJobs = extendedJobs.obscured_jobs
@@ -351,6 +374,8 @@
}
}
let lastQueueTs: string | undefined = undefined
async function syncer() {
if (success == 'waiting') {
minTs = undefined
@@ -379,40 +404,47 @@
if (success == 'running') {
loadJobsIntern(false)
} else {
let ts: string | undefined = undefined
let minQueueCreatedAt: string | undefined = undefined
let completedTs: string | undefined = undefined
let cursor = 0
while (cursor < jobs.length && minTs == undefined) {
let invCursor = jobs.length - 1 - cursor
let isQueuedJob = invCursor == 0 || jobs[invCursor].type == 'QueuedJob'
if (isQueuedJob) {
if (cursor > 0) {
let inc = invCursor == 0 && jobs[invCursor].type == 'CompletedJob' ? 0 : 1
const date = new Date(jobs[invCursor + inc]?.created_at!)
date.setMilliseconds(date.getMilliseconds() + 1)
ts = date.toISOString()
if (minTs == undefined) {
while (cursor < jobs.length) {
const cjob = jobs[cursor]
if (cjob.type == 'QueuedJob') {
minQueueCreatedAt = cjob.created_at
} else if (cjob.type == 'CompletedJob' && completedTs == undefined) {
completedTs = new Date(cjob.completed_at!).toISOString()
}
break
cursor++
}
cursor++
}
let queueTs: string | undefined
if (minQueueCreatedAt) {
const queueTs = new Date(minQueueCreatedAt).toISOString()
lastQueueTs = queueTs
} else {
queueTs = lastQueueTs
}
loading = true
let newJobs: Job[]
if (concurrencyKey == null || concurrencyKey === '') {
newJobs = await fetchJobs(maxTs, minTs ?? ts, undefined, undefined)
newJobs = await fetchJobs(maxTs, minTs ?? completedTs, queueTs)
} else {
// Obscured jobs have no ids, so we have to do the full request
extendedJobs = await fetchExtendedJobs(concurrencyKey, maxTs, undefined, minTs ?? ts)
extendedJobs = await fetchExtendedJobs(concurrencyKey, maxTs, minTs ?? completedTs)
externalJobs = computeExternalJobs(extendedJobs.obscured_jobs)
// Filter on minTs here and not in the backend
// to get enough data for the concurrency graph
newJobs = sortMinDate(minTs ?? ts, extendedJobs.jobs)
newJobs = sortMinDate(minTs ?? completedTs, extendedJobs.jobs)
}
if (newJobs && newJobs.length > 0 && jobs) {
jobs = updateWithNewJobs(jobs, newJobs)
jobs = jobs
if (concurrencyKey == null || concurrencyKey === '') {
if (!extendedJobs) {
extendedJobs = { jobs: jobs, obscured_jobs: [] } as ExtendedJobs
@@ -3,12 +3,23 @@
import { Button } from '../common'
import { createEventDispatcher } from 'svelte'
export let minTs: string | undefined
export let maxTs: string | undefined
export let loading: boolean = false
export let selectedManualDate = 0
export let loadText: string | undefined = undefined
export let serviceLogsChoices: boolean = false
interface Props {
minTs: string | undefined;
maxTs: string | undefined;
loading?: boolean;
selectedManualDate?: number;
loadText?: string | undefined;
serviceLogsChoices?: boolean;
}
let {
minTs = $bindable(),
maxTs = $bindable(),
loading = false,
selectedManualDate = $bindable(0),
loadText = undefined,
serviceLogsChoices = false
}: Props = $props();
export function computeMinMax(): { minTs: string; maxTs: string | undefined } | undefined {
return manualDates[selectedManualDate].computeMinMax()
@@ -62,7 +73,7 @@
}
]
$: manualDates = [
let manualDates = $derived([
{
label: loadText ?? 'Last 1000 runs',
computeMinMax: () => {
@@ -70,7 +81,7 @@
}
},
...fixedManualDates
]
])
const dispatch = createEventDispatcher()
</script>
+11 -6
View File
@@ -107,7 +107,7 @@
<div
class={twMerge(
'hover:bg-surface-hover cursor-pointer',
selected ? 'bg-surface-accent-selected/30' : '',
selected ? 'bg-surface-accent-selected' : '',
'grid items-center h-full'
)}
class:grid-runs-table={!containsLabel && !selectionMode && showTag}
@@ -181,9 +181,14 @@
<div class="overflow-hidden min-w-0">
<div class="flex flex-row items-center gap-1 text-secondary text-2xs">
{#if job}
{#if 'started_at' in job && job.started_at}
{isJobRecent ? 'Started' : ''}
<TimeAgo bind:isRecent={isJobRecent} agoOnlyIfRecent date={job.started_at ?? ''} />
{#if ('started_at' in job && job.started_at) || ('completed_at' in job && job.completed_at)}
{#if 'completed_at' in job && job.completed_at}
{isJobRecent ? 'Ended' : ''}
<TimeAgo bind:isRecent={isJobRecent} agoOnlyIfRecent date={job.completed_at ?? ''} />
{:else if 'started_at' in job && job.started_at}
{isJobRecent ? 'Started' : ''}
<TimeAgo bind:isRecent={isJobRecent} agoOnlyIfRecent date={job.started_at ?? ''} />
{/if}
{#if job && (job.self_wait_time_ms || job.aggregate_wait_time_ms)}
<WaitTimeWarning
self_wait_time_ms={job.self_wait_time_ms}
@@ -200,12 +205,12 @@
Cancelling job... (created <TimeAgo agoOnlyIfRecent date={job.created_at || ''} />)
{/if}
{:else if `scheduled_for` in job && job.scheduled_for && forLater(job.scheduled_for)}
Waiting for executor (scheduled for <TimeAgo
Waiting executor (<TimeAgo
agoOnlyIfRecent
date={job.scheduled_for || ''}
/>)
{:else}
Waiting for executor (created <TimeAgo agoOnlyIfRecent date={job.created_at || ''} />)
Waiting executor (<TimeAgo agoOnlyIfRecent date={job.created_at || ''} />)
{/if}
{/if}
</div>
@@ -37,7 +37,7 @@
}: Props = $props()
function getTime(job: Job): string | undefined {
return job['started_at'] ?? job['scheduled_for'] ?? job['created_at']
return job['completed_at'] ?? job['started_at'] ?? job['scheduled_for'] ?? job['created_at']
}
function groupJobsByDay(jobs: Job[]): {
@@ -2,6 +2,7 @@
import { createEventDispatcher } from 'svelte'
import { Button } from '../common'
import { Plus } from 'lucide-svelte'
import TextInput from '../text_input/TextInput.svelte'
let name: string = ''
@@ -13,15 +14,15 @@
}
</script>
<div class="flex flex-row gap-2">
<input
bind:value={name}
placeholder="Field name"
on:keydown={(event) => {
if (event.key === 'Enter') {
addField()
<div class="flex gap-2 whitespace-nowrap">
<TextInput
inputProps={{
placeholder: 'Field name',
onkeydown: (event) => {
if (event.key === 'Enter') addField()
}
}}
bind:value={name}
/>
<Button
variant="accent"
@@ -188,7 +188,7 @@
{#snippet children()}
<DrawerContent title="UI Customisation" on:close={() => schemaFormDrawer?.closeDrawer()}>
<EditableSchemaForm
schemaFormClassName="h-full"
schemaFormClassName="min-h-full"
bind:this={editableSchemaForm}
bind:schema
isAppInput

Some files were not shown because too many files have changed in this diff Show More