diff --git a/CHANGELOG.md b/CHANGELOG.md index 0386e08fbb..9249a453a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.547.0](https://github.com/windmill-labs/windmill/compare/v1.546.1...v1.547.0) (2025-09-23) + + +### Features + +* add dyn select for flow step [#6662](https://github.com/windmill-labs/windmill/issues/6662) ([b64e509](https://github.com/windmill-labs/windmill/commit/b64e509e60fadc631ccd6090654d523d08c06e35)) + + +### Bug Fixes + +* **cli:** improve result printing of the CLI ([a7cbc28](https://github.com/windmill-labs/windmill/commit/a7cbc289af1eaacbb50d53f2bcb4a14f50d420ef)) +* improve scripts duplicity error in global search ([2de7134](https://github.com/windmill-labs/windmill/commit/2de7134b85d8249f661e3db34ff43c29b13fa0aa)) + ## [1.546.1](https://github.com/windmill-labs/windmill/compare/v1.546.0...v1.546.1) (2025-09-23) diff --git a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json index d29a18c691..e7ed0aee65 100644 --- a/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json +++ b/backend/.sqlx/query-07168aaf14cb6beff0ad4274b441f7f387f5055c47f493271d26731336257384.json @@ -46,11 +46,11 @@ ] }, "nullable": [ - true, - true, - true, - true, - true, + false, + false, + false, + false, + false, true, true ] diff --git a/backend/.sqlx/query-16e4b1bead9fc77fd98658b8cb8cc6d6bf1df758b30e99bd661da866062ef14f.json b/backend/.sqlx/query-16e4b1bead9fc77fd98658b8cb8cc6d6bf1df758b30e99bd661da866062ef14f.json deleted file mode 100644 index 1af42ff529..0000000000 --- a/backend/.sqlx/query-16e4b1bead9fc77fd98658b8cb8cc6d6bf1df758b30e99bd661da866062ef14f.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT hash FROM script WHERE path = $1 AND workspace_id = $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "hash", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "16e4b1bead9fc77fd98658b8cb8cc6d6bf1df758b30e99bd661da866062ef14f" -} diff --git a/backend/.sqlx/query-d6f62e25faf271876874fc09ee460313159bb6ad91227f5dec37cd28006e2add.json b/backend/.sqlx/query-79d6b757c9556cfcf0c98f52035b5f1a9036b6005764b79c415373a5d39c3211.json similarity index 54% rename from backend/.sqlx/query-d6f62e25faf271876874fc09ee460313159bb6ad91227f5dec37cd28006e2add.json rename to backend/.sqlx/query-79d6b757c9556cfcf0c98f52035b5f1a9036b6005764b79c415373a5d39c3211.json index c4c138a886..7b0d64c691 100644 --- a/backend/.sqlx/query-d6f62e25faf271876874fc09ee460313159bb6ad91227f5dec37cd28006e2add.json +++ b/backend/.sqlx/query-79d6b757c9556cfcf0c98f52035b5f1a9036b6005764b79c415373a5d39c3211.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n result AS \"result: sqlx::types::Json>\",\n result_columns,\n status = 'success' AS \"success!\"\n FROM v2_job_completed\n WHERE id = $1 AND workspace_id = $2", + "query": "\n SELECT\n result AS \"result: sqlx::types::Json>\",\n result_columns,\n status = 'success' AS \"success!\"\n FROM \n v2_job_completed\n WHERE \n id = $1 AND \n workspace_id = $2\n ", "describe": { "columns": [ { @@ -31,5 +31,5 @@ null ] }, - "hash": "d6f62e25faf271876874fc09ee460313159bb6ad91227f5dec37cd28006e2add" + "hash": "79d6b757c9556cfcf0c98f52035b5f1a9036b6005764b79c415373a5d39c3211" } diff --git a/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json b/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json deleted file mode 100644 index 6f08d98113..0000000000 --- a/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO script (summary, description, dedicated_worker, content, workspace_id, path, hash, language, tag, created_by, lock) VALUES ('', '', true, $1, $2, $3, $4, $5, $6, $7, '') ON CONFLICT (workspace_id, hash) DO NOTHING", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Varchar", - "Varchar", - "Int8", - { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp", - "oracledb", - "nu", - "java", - "duckdb", - "ruby" - ] - } - } - }, - "Varchar", - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf" -} diff --git a/backend/.sqlx/query-85705fc3d7f8ba5f1b12d5fb222c38fc64deb1226aab9dc3bc4465324fce37d1.json b/backend/.sqlx/query-85705fc3d7f8ba5f1b12d5fb222c38fc64deb1226aab9dc3bc4465324fce37d1.json deleted file mode 100644 index bce7324fb6..0000000000 --- a/backend/.sqlx/query-85705fc3d7f8ba5f1b12d5fb222c38fc64deb1226aab9dc3bc4465324fce37d1.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO v2_job_queue (id, workspace_id, scheduled_for, tag) SELECT unnest($1::uuid[]), $2, now(), $3", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "UuidArray", - "Varchar", - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "85705fc3d7f8ba5f1b12d5fb222c38fc64deb1226aab9dc3bc4465324fce37d1" -} diff --git a/backend/.sqlx/query-23eb4d45bf2df21e22fc6c9590b96b0a7dbdd27f85c7d886eded79b3af83731a.json b/backend/.sqlx/query-9ebf262393fc4a29e8f09b304dd99e786fe78dd21721e8f54dc943dd571a7e08.json similarity index 65% rename from backend/.sqlx/query-23eb4d45bf2df21e22fc6c9590b96b0a7dbdd27f85c7d886eded79b3af83731a.json rename to backend/.sqlx/query-9ebf262393fc4a29e8f09b304dd99e786fe78dd21721e8f54dc943dd571a7e08.json index ecaefdeb62..53c7562d03 100644 --- a/backend/.sqlx/query-23eb4d45bf2df21e22fc6c9590b96b0a7dbdd27f85c7d886eded79b3af83731a.json +++ b/backend/.sqlx/query-9ebf262393fc4a29e8f09b304dd99e786fe78dd21721e8f54dc943dd571a7e08.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO websocket_trigger (\n workspace_id,\n path,\n url,\n script_path,\n is_flow,\n enabled,\n filters,\n initial_messages,\n url_runnable_args,\n edited_by,\n can_return_message,\n email,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, now(), $13, $14, $15\n )\n ", + "query": "\n INSERT INTO websocket_trigger (\n workspace_id,\n path,\n url,\n script_path,\n is_flow,\n enabled,\n filters,\n initial_messages,\n url_runnable_args,\n edited_by,\n can_return_message,\n can_return_error_result,\n email,\n edited_at,\n error_handler_path,\n error_handler_args,\n retry\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, now(), $14, $15, $16\n )\n ", "describe": { "columns": [], "parameters": { @@ -16,6 +16,7 @@ "Jsonb", "Varchar", "Bool", + "Bool", "Varchar", "Varchar", "Jsonb", @@ -24,5 +25,5 @@ }, "nullable": [] }, - "hash": "23eb4d45bf2df21e22fc6c9590b96b0a7dbdd27f85c7d886eded79b3af83731a" + "hash": "9ebf262393fc4a29e8f09b304dd99e786fe78dd21721e8f54dc943dd571a7e08" } diff --git a/backend/.sqlx/query-a0b3e10e077d30c1da135dff9feca3761d400391f1f46a8294da3e6c9af63887.json b/backend/.sqlx/query-a0b3e10e077d30c1da135dff9feca3761d400391f1f46a8294da3e6c9af63887.json deleted file mode 100644 index 1afc61978e..0000000000 --- a/backend/.sqlx/query-a0b3e10e077d30c1da135dff9feca3761d400391f1f46a8294da3e6c9af63887.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO v2_job_status (id, flow_status) SELECT unnest($1::uuid[]), $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "UuidArray", - "Jsonb" - ] - }, - "nullable": [] - }, - "hash": "a0b3e10e077d30c1da135dff9feca3761d400391f1f46a8294da3e6c9af63887" -} diff --git a/backend/.sqlx/query-ab04cda71f8e2be9acbecabe1ee5ef756b8e5c1955fbe111df9ee171dc262338.json b/backend/.sqlx/query-ab04cda71f8e2be9acbecabe1ee5ef756b8e5c1955fbe111df9ee171dc262338.json deleted file mode 100644 index e07a3ccdd7..0000000000 --- a/backend/.sqlx/query-ab04cda71f8e2be9acbecabe1ee5ef756b8e5c1955fbe111df9ee171dc262338.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO v2_job (id, runnable_id, runnable_path, kind, script_lang, tag, created_by, permissioned_as, permissioned_as_email, workspace_id, raw_flow) (SELECT gen_random_uuid(), $1, $2, $3, $4, $5, $6, $7, $8, $9, $10 FROM generate_series(1, 1)) RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Uuid" - } - ], - "parameters": { - "Left": [ - "Int8", - "Varchar", - { - "Custom": { - "name": "job_kind", - "kind": { - "Enum": [ - "script", - "preview", - "flow", - "dependencies", - "flowpreview", - "script_hub", - "identity", - "flowdependencies", - "http", - "graphql", - "postgresql", - "noop", - "appdependencies", - "deploymentcallback", - "singlescriptflow", - "flowscript", - "flownode", - "appscript", - "aiagent" - ] - } - } - }, - { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp", - "oracledb", - "nu", - "java", - "duckdb", - "ruby" - ] - } - } - }, - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Jsonb" - ] - }, - "nullable": [ - false - ] - }, - "hash": "ab04cda71f8e2be9acbecabe1ee5ef756b8e5c1955fbe111df9ee171dc262338" -} diff --git a/backend/.sqlx/query-b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76.json b/backend/.sqlx/query-b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76.json index 99269c9851..54e94cfb8f 100644 --- a/backend/.sqlx/query-b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76.json +++ b/backend/.sqlx/query-b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76.json @@ -18,8 +18,8 @@ "Left": [] }, "nullable": [ - true, - false + false, + true ] }, "hash": "b3dbdfb50ee8118bdaed3164b210cb549a34b96554ae1872355b90304f5dcb76" diff --git a/backend/.sqlx/query-b4a9abcb38997587b28655b0f4a212a5bd4039b57fab20b163617e33a4c9dd46.json b/backend/.sqlx/query-b4a9abcb38997587b28655b0f4a212a5bd4039b57fab20b163617e33a4c9dd46.json deleted file mode 100644 index a49baeefaf..0000000000 --- a/backend/.sqlx/query-b4a9abcb38997587b28655b0f4a212a5bd4039b57fab20b163617e33a4c9dd46.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO v2_job_runtime (id) SELECT unnest($1::uuid[])", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "UuidArray" - ] - }, - "nullable": [] - }, - "hash": "b4a9abcb38997587b28655b0f4a212a5bd4039b57fab20b163617e33a4c9dd46" -} diff --git a/backend/.sqlx/query-35b211d19e53da4b64b0bd097284de3236ab939e47a1fc2b15ffc9607b552f8d.json b/backend/.sqlx/query-b5f6870444fc97d8beab3cf61c91e58936138d80a97b423c17338ba069b6a3aa.json similarity index 67% rename from backend/.sqlx/query-35b211d19e53da4b64b0bd097284de3236ab939e47a1fc2b15ffc9607b552f8d.json rename to backend/.sqlx/query-b5f6870444fc97d8beab3cf61c91e58936138d80a97b423c17338ba069b6a3aa.json index aa52f752ae..1d8fa42e31 100644 --- a/backend/.sqlx/query-35b211d19e53da4b64b0bd097284de3236ab939e47a1fc2b15ffc9607b552f8d.json +++ b/backend/.sqlx/query-b5f6870444fc97d8beab3cf61c91e58936138d80a97b423c17338ba069b6a3aa.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n UPDATE \n websocket_trigger\n SET\n url = $1,\n script_path = $2,\n path = $3,\n is_flow = $4,\n filters = $5,\n initial_messages = $6,\n url_runnable_args = $7,\n edited_by = $8,\n email = $9,\n can_return_message = $10,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $13,\n error_handler_args = $14,\n retry = $15\n WHERE\n workspace_id = $11 AND path = $12\n ", + "query": "\n UPDATE \n websocket_trigger\n SET\n url = $1,\n script_path = $2,\n path = $3,\n is_flow = $4,\n filters = $5,\n initial_messages = $6,\n url_runnable_args = $7,\n edited_by = $8,\n email = $9,\n can_return_message = $10,\n can_return_error_result = $11,\n edited_at = now(),\n server_id = NULL,\n error = NULL,\n error_handler_path = $14,\n error_handler_args = $15,\n retry = $16\n WHERE\n workspace_id = $12 AND path = $13\n ", "describe": { "columns": [], "parameters": { @@ -15,6 +15,7 @@ "Varchar", "Varchar", "Bool", + "Bool", "Text", "Text", "Varchar", @@ -24,5 +25,5 @@ }, "nullable": [] }, - "hash": "35b211d19e53da4b64b0bd097284de3236ab939e47a1fc2b15ffc9607b552f8d" + "hash": "b5f6870444fc97d8beab3cf61c91e58936138d80a97b423c17338ba069b6a3aa" } diff --git a/backend/.sqlx/query-ff0403790674cdb07022af71c2377afbd8b3a660b3be27514b517c077c63c238.json b/backend/.sqlx/query-ff0403790674cdb07022af71c2377afbd8b3a660b3be27514b517c077c63c238.json deleted file mode 100644 index 0e42bd0fdb..0000000000 --- a/backend/.sqlx/query-ff0403790674cdb07022af71c2377afbd8b3a660b3be27514b517c077c63c238.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO v2_job (id, runnable_id, runnable_path, kind, script_lang, tag, created_by, permissioned_as, permissioned_as_email, workspace_id) (SELECT gen_random_uuid(), $1, $2, $3, $4, $5, $6, $7, $8, $9 FROM generate_series(1, $10)) RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Uuid" - } - ], - "parameters": { - "Left": [ - "Int8", - "Varchar", - { - "Custom": { - "name": "job_kind", - "kind": { - "Enum": [ - "script", - "preview", - "flow", - "dependencies", - "flowpreview", - "script_hub", - "identity", - "flowdependencies", - "http", - "graphql", - "postgresql", - "noop", - "appdependencies", - "deploymentcallback", - "singlescriptflow", - "flowscript", - "flownode", - "appscript", - "aiagent" - ] - } - } - }, - { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp", - "oracledb", - "nu", - "java", - "duckdb", - "ruby" - ] - } - } - }, - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Int4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "ff0403790674cdb07022af71c2377afbd8b3a660b3be27514b517c077c63c238" -} diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 4419859554..9c3b85cf4f 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -5812,20 +5812,6 @@ dependencies = [ "seq-macro", ] -[[package]] -name = "generator" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows 0.61.3", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -7582,9 +7568,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.175" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libffi" @@ -7762,19 +7748,6 @@ dependencies = [ "prost-types", ] -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - [[package]] name = "lru" version = "0.12.5" @@ -8199,20 +8172,19 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.10" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" dependencies = [ "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", - "loom", + "equivalent", "parking_lot 0.12.4", "portable-atomic", "rustc_version 0.4.1", "smallvec", "tagptr", - "thiserror 1.0.69", "uuid", ] @@ -15135,7 +15107,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windmill" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "aws-sdk-config", @@ -15195,7 +15167,7 @@ dependencies = [ [[package]] name = "windmill-api" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "argon2", @@ -15315,7 +15287,7 @@ dependencies = [ [[package]] name = "windmill-api-client" -version = "1.546.1" +version = "1.547.0" dependencies = [ "base64 0.22.1", "chrono", @@ -15330,7 +15302,7 @@ dependencies = [ [[package]] name = "windmill-audit" -version = "1.546.1" +version = "1.547.0" dependencies = [ "chrono", "serde", @@ -15343,7 +15315,7 @@ dependencies = [ [[package]] name = "windmill-autoscaling" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "axum", @@ -15362,7 +15334,7 @@ dependencies = [ [[package]] name = "windmill-common" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "async-recursion", @@ -15446,7 +15418,7 @@ dependencies = [ [[package]] name = "windmill-git-sync" -version = "1.546.1" +version = "1.547.0" dependencies = [ "regex", "serde", @@ -15461,7 +15433,7 @@ dependencies = [ [[package]] name = "windmill-indexer" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "bytes", @@ -15485,7 +15457,7 @@ dependencies = [ [[package]] name = "windmill-macros" -version = "1.546.1" +version = "1.547.0" dependencies = [ "itertools 0.14.0", "lazy_static", @@ -15497,7 +15469,7 @@ dependencies = [ [[package]] name = "windmill-parser" -version = "1.546.1" +version = "1.547.0" dependencies = [ "convert_case 0.6.0", "serde", @@ -15506,7 +15478,7 @@ dependencies = [ [[package]] name = "windmill-parser-bash" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "lazy_static", @@ -15518,7 +15490,7 @@ dependencies = [ [[package]] name = "windmill-parser-csharp" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "serde_json", @@ -15530,7 +15502,7 @@ dependencies = [ [[package]] name = "windmill-parser-go" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "gosyn", @@ -15542,7 +15514,7 @@ dependencies = [ [[package]] name = "windmill-parser-graphql" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "lazy_static", @@ -15554,7 +15526,7 @@ dependencies = [ [[package]] name = "windmill-parser-java" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "serde_json", @@ -15566,7 +15538,7 @@ dependencies = [ [[package]] name = "windmill-parser-nu" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "nu-parser", @@ -15577,7 +15549,7 @@ dependencies = [ [[package]] name = "windmill-parser-php" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "itertools 0.14.0", @@ -15588,7 +15560,7 @@ dependencies = [ [[package]] name = "windmill-parser-py" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "itertools 0.14.0", @@ -15600,7 +15572,7 @@ dependencies = [ [[package]] name = "windmill-parser-py-imports" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "async-recursion", @@ -15623,7 +15595,7 @@ dependencies = [ [[package]] name = "windmill-parser-ruby" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "lazy_static", @@ -15637,7 +15609,7 @@ dependencies = [ [[package]] name = "windmill-parser-rust" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -15654,7 +15626,7 @@ dependencies = [ [[package]] name = "windmill-parser-sql" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "lazy_static", @@ -15668,7 +15640,7 @@ dependencies = [ [[package]] name = "windmill-parser-ts" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "lazy_static", @@ -15686,7 +15658,7 @@ dependencies = [ [[package]] name = "windmill-parser-wasm" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "getrandom 0.2.16", @@ -15711,7 +15683,7 @@ dependencies = [ [[package]] name = "windmill-parser-yaml" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "serde_json", @@ -15721,7 +15693,7 @@ dependencies = [ [[package]] name = "windmill-queue" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "async-recursion", @@ -15754,7 +15726,7 @@ dependencies = [ [[package]] name = "windmill-sql-datatype-parser-wasm" -version = "1.546.1" +version = "1.547.0" dependencies = [ "wasm-bindgen", "wasm-bindgen-test", @@ -15764,7 +15736,7 @@ dependencies = [ [[package]] name = "windmill-worker" -version = "1.546.1" +version = "1.547.0" dependencies = [ "anyhow", "async-once-cell", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 4e8811a52c..e852412f7c 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "windmill" -version = "1.546.1" +version = "1.547.0" authors.workspace = true edition.workspace = true @@ -34,7 +34,7 @@ members = [ exclude = ["./windmill-duckdb-ffi-internal"] [workspace.package] -version = "1.546.1" +version = "1.547.0" authors = ["Ruben Fiszel "] edition = "2021" diff --git a/backend/migrations/20250923094837_websocket_can_return_error_result.down.sql b/backend/migrations/20250923094837_websocket_can_return_error_result.down.sql new file mode 100644 index 0000000000..51456cbf29 --- /dev/null +++ b/backend/migrations/20250923094837_websocket_can_return_error_result.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +ALTER TABLE websocket_trigger DROP COLUMN can_return_error_result; \ No newline at end of file diff --git a/backend/migrations/20250923094837_websocket_can_return_error_result.up.sql b/backend/migrations/20250923094837_websocket_can_return_error_result.up.sql new file mode 100644 index 0000000000..085a575e38 --- /dev/null +++ b/backend/migrations/20250923094837_websocket_can_return_error_result.up.sql @@ -0,0 +1,2 @@ +-- Add up migration script here +ALTER TABLE websocket_trigger ADD COLUMN can_return_error_result BOOLEAN NOT NULL DEFAULT FALSE; \ No newline at end of file diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 3c2d957947..ba53fb2c37 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -1,7 +1,7 @@ openapi: "3.0.3" info: - version: 1.546.1 + version: 1.547.0 title: Windmill API contact: @@ -16426,6 +16426,8 @@ components: $ref: "#/components/schemas/ScriptArgs" can_return_message: type: boolean + can_return_error_result: + type: boolean error_handler_path: type: string error_handler_args: @@ -16438,6 +16440,7 @@ components: - enabled - filters - can_return_message + - can_return_error_result NewWebsocketTrigger: type: object @@ -16471,6 +16474,8 @@ components: $ref: "#/components/schemas/ScriptArgs" can_return_message: type: boolean + can_return_error_result: + type: boolean error_handler_path: type: string error_handler_args: @@ -16485,6 +16490,7 @@ components: - is_flow - filters - can_return_message + - can_return_error_result EditWebsocketTrigger: type: object @@ -16516,6 +16522,8 @@ components: $ref: "#/components/schemas/ScriptArgs" can_return_message: type: boolean + can_return_error_result: + type: boolean error_handler_path: type: string error_handler_args: @@ -16530,6 +16538,7 @@ components: - is_flow - filters - can_return_message + - can_return_error_result WebsocketTriggerInitialMessage: anyOf: - type: object diff --git a/backend/windmill-api/src/jobs.rs b/backend/windmill-api/src/jobs.rs index 5bd8410ff7..596e404629 100644 --- a/backend/windmill-api/src/jobs.rs +++ b/backend/windmill-api/src/jobs.rs @@ -4523,12 +4523,17 @@ pub async fn run_wait_result_internal( if result.is_none() { let row = sqlx::query!( - "SELECT + " + SELECT result AS \"result: sqlx::types::Json>\", result_columns, status = 'success' AS \"success!\" - FROM v2_job_completed - WHERE id = $1 AND workspace_id = $2", + FROM + v2_job_completed + WHERE + id = $1 AND + workspace_id = $2 + ", uuid, &w_id ) diff --git a/backend/windmill-api/src/triggers/trigger_helpers.rs b/backend/windmill-api/src/triggers/trigger_helpers.rs index c95b74761e..a1a5f62e50 100644 --- a/backend/windmill-api/src/triggers/trigger_helpers.rs +++ b/backend/windmill-api/src/triggers/trigger_helpers.rs @@ -623,7 +623,7 @@ pub async fn trigger_runnable_and_wait_for_raw_result( error_handler_path: Option<&str>, error_handler_args: Option<&sqlx::types::Json>>, trigger_path: String, -) -> Result> { +) -> Result<(Box, bool)> { let username = authed.username.clone(); let (uuid, delete_after_use, early_return) = trigger_runnable_inner( db, @@ -656,6 +656,36 @@ pub async fn trigger_runnable_and_wait_for_raw_result( delete_job_metadata_after_use(&db, uuid).await?; } + Ok((result, success)) +} + +pub async fn trigger_runnable_and_wait_for_raw_result_with_error_ctx( + db: &DB, + user_db: Option, + authed: ApiAuthed, + workspace_id: &str, + runnable_path: &str, + is_flow: bool, + args: PushArgsOwned, + retry: Option<&sqlx::types::Json>, + error_handler_path: Option<&str>, + error_handler_args: Option<&sqlx::types::Json>>, + trigger_path: String, +) -> Result> { + let (result, success) = trigger_runnable_and_wait_for_raw_result( + db, + user_db, + authed, + workspace_id, + runnable_path, + is_flow, + args, + retry, + error_handler_path, + error_handler_args, + trigger_path, + ).await?; + if !success { Err(windmill_common::error::Error::internal_err(format!( "{} {runnable_path} failed: {:?}", diff --git a/backend/windmill-api/src/triggers/websocket/handler.rs b/backend/windmill-api/src/triggers/websocket/handler.rs index 0a321a450c..827367e195 100644 --- a/backend/windmill-api/src/triggers/websocket/handler.rs +++ b/backend/windmill-api/src/triggers/websocket/handler.rs @@ -40,6 +40,7 @@ impl TriggerCrud for WebsocketTrigger { "initial_messages", "url_runnable_args", "can_return_message", + "can_return_error_result", ]; const IS_ALLOWED_ON_CLOUD: bool = false; @@ -105,13 +106,14 @@ impl TriggerCrud for WebsocketTrigger { url_runnable_args, edited_by, can_return_message, + can_return_error_result, email, edited_at, error_handler_path, error_handler_args, retry ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, now(), $13, $14, $15 + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, now(), $14, $15, $16 ) "#, w_id, @@ -128,6 +130,7 @@ impl TriggerCrud for WebsocketTrigger { .map(|v| SqlxJson(serde_json::value::to_raw_value(&v).unwrap())) as _, authed.username, trigger.config.can_return_message, + trigger.config.can_return_error_result, authed.email, trigger.error_handling.error_handler_path, trigger.error_handling.error_handler_args as _, @@ -177,14 +180,15 @@ impl TriggerCrud for WebsocketTrigger { edited_by = $8, email = $9, can_return_message = $10, + can_return_error_result = $11, edited_at = now(), server_id = NULL, error = NULL, - error_handler_path = $13, - error_handler_args = $14, - retry = $15 + error_handler_path = $14, + error_handler_args = $15, + retry = $16 WHERE - workspace_id = $11 AND path = $12 + workspace_id = $12 AND path = $13 ", trigger.config.url, trigger.base.script_path, @@ -200,6 +204,7 @@ impl TriggerCrud for WebsocketTrigger { &authed.username, &authed.email, trigger.config.can_return_message, + trigger.config.can_return_error_result, w_id, path, trigger.error_handling.error_handler_path, diff --git a/backend/windmill-api/src/triggers/websocket/listener.rs b/backend/windmill-api/src/triggers/websocket/listener.rs index 7fb22f2b08..9a3f83a016 100644 --- a/backend/windmill-api/src/triggers/websocket/listener.rs +++ b/backend/windmill-api/src/triggers/websocket/listener.rs @@ -1,7 +1,10 @@ use super::WebsocketTrigger; use crate::triggers::{ listener::ListeningTrigger, - trigger_helpers::{trigger_runnable, trigger_runnable_and_wait_for_raw_result, TriggerJobArgs}, + trigger_helpers::{ + trigger_runnable, trigger_runnable_and_wait_for_raw_result, + trigger_runnable_and_wait_for_raw_result_with_error_ctx, TriggerJobArgs, + }, websocket::WebsocketConfig, Listener, }; @@ -42,7 +45,7 @@ impl ListeningTrigger { self.trigger_config.url_runnable_args.as_ref().map(|r| &r.0), )?; - let result = trigger_runnable_and_wait_for_raw_result( + let result = trigger_runnable_and_wait_for_raw_result_with_error_ctx( db, None, authed, @@ -116,7 +119,7 @@ impl ListeningTrigger { } let authed = authed_o.clone().unwrap(); - let result = trigger_runnable_and_wait_for_raw_result( + let result = trigger_runnable_and_wait_for_raw_result_with_error_ctx( db, None, authed.clone(), @@ -404,6 +407,7 @@ impl Listener for WebsocketTrigger { let error_handler_path = error_handler_path.map(|s| s.to_string()); let error_handler_args = error_handler_args.cloned(); let trigger_path = path.clone(); + let can_return_error_result = trigger_config.can_return_error_result; let handle_response_f = async move { tokio::select! { _ = killpill_rx.recv() => { @@ -422,7 +426,11 @@ impl Listener for WebsocketTrigger { error_handler_args.as_ref(), format!("websocket_trigger/{}", trigger_path), ) => { - if let Ok(result) = result.map(|r| r.get().to_owned()) { + if let Ok((result, success)) = result { + if !success && !can_return_error_result { + return; + } + let result = result.get().to_owned(); // only send the result if it's not null if result != "null" { tracing::info!("Sending job result to WebSocket {}", url); diff --git a/backend/windmill-api/src/triggers/websocket/mod.rs b/backend/windmill-api/src/triggers/websocket/mod.rs index 7ed67e1565..86d3bd735b 100644 --- a/backend/windmill-api/src/triggers/websocket/mod.rs +++ b/backend/windmill-api/src/triggers/websocket/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::{ db::ApiAuthed, - triggers::trigger_helpers::{trigger_runnable_and_wait_for_raw_result, TriggerJobArgs}, + triggers::trigger_helpers::{trigger_runnable_and_wait_for_raw_result_with_error_ctx, TriggerJobArgs}, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; @@ -40,6 +40,8 @@ pub struct WebsocketConfig { pub url_runnable_args: Option>>, #[serde(default)] pub can_return_message: bool, + #[serde(default)] + pub can_return_error_result: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -49,6 +51,7 @@ pub struct WebsocketConfigRequest { initial_messages: Option>, url_runnable_args: Option, can_return_message: bool, + can_return_error_result: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -97,7 +100,7 @@ pub async fn get_url_from_runnable_value( let args = value_to_args_hashmap(args)?; - let result = trigger_runnable_and_wait_for_raw_result( + let result = trigger_runnable_and_wait_for_raw_result_with_error_ctx( db, None, authed, diff --git a/backend/windmill-worker/src/python_executor.rs b/backend/windmill-worker/src/python_executor.rs index 57936969b8..b31de6e184 100644 --- a/backend/windmill-worker/src/python_executor.rs +++ b/backend/windmill-worker/src/python_executor.rs @@ -2054,6 +2054,13 @@ pub async fn handle_python_reqs( .unwrap_or(Err(anyhow!("Problem by joining handle"))) { failed = true; + append_logs( + &job_id, + w_id, + format!("\nEnv installation failed: {:?}", e), + conn, + ) + .await; tracing::warn!( workspace_id = %w_id, "Env installation failed: {:?}", diff --git a/benchmarks/lib.ts b/benchmarks/lib.ts index 617d849b16..fdfe9779ba 100644 --- a/benchmarks/lib.ts +++ b/benchmarks/lib.ts @@ -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.546.1"; +export const VERSION = "v1.547.0"; export async function login(email: string, password: string): Promise { return await windmill.UserService.login({ diff --git a/cli/src/commands/flow/flow.ts b/cli/src/commands/flow/flow.ts index 93938e6254..b6a59f95e1 100644 --- a/cli/src/commands/flow/flow.ts +++ b/cli/src/commands/flow/flow.ts @@ -14,7 +14,6 @@ import { FSFSElement, elementsToMap, ignoreF } from "../sync/sync.ts"; import { Flow } from "../../../gen/types.gen.ts"; import { replaceInlineScripts } from "../../../windmill-utils-internal/src/inline-scripts/replacer.ts"; - export interface FlowFile { summary: string; description?: string; @@ -55,7 +54,7 @@ export async function pushFlow( async (path: string) => await Deno.readTextFile(localPath + path), log, localPath, - SEP, + SEP ); if (flow) { @@ -191,7 +190,7 @@ async function run( workspace: workspace.workspaceId, id, }); - log.info(jobInfo.result ?? {}); + log.info(JSON.stringify(jobInfo.result ?? {}, null, 2)); } async function generateLocks( @@ -201,14 +200,23 @@ async function generateLocks( } & SyncOptions, folder: string | undefined ) { - const useRawReqs = opts.useRawRequirements || Deno.env.get("USE_RAW_REQUIREMENTS") === "true"; + const useRawReqs = + opts.useRawRequirements || Deno.env.get("USE_RAW_REQUIREMENTS") === "true"; const workspace = await resolveWorkspace(opts); await requireLogin(opts); opts = await mergeConfigWithConfigFile(opts); if (folder) { // read script metadata file - await generateFlowLockInternal(folder, false, workspace, opts, undefined, undefined, useRawReqs); + await generateFlowLockInternal( + folder, + false, + workspace, + opts, + undefined, + undefined, + useRawReqs + ); } else { const ignore = await ignoreF(opts); const elems = Object.keys( @@ -229,7 +237,15 @@ async function generateLocks( let hasAny = false; for (const folder of elems) { - const candidate = await generateFlowLockInternal(folder, true, workspace, opts, undefined, undefined, useRawReqs); + const candidate = await generateFlowLockInternal( + folder, + true, + workspace, + opts, + undefined, + undefined, + useRawReqs + ); if (candidate) { hasAny = true; log.info(colors.green(`+ ${candidate}`)); @@ -251,7 +267,15 @@ async function generateLocks( return; } for (const folder of elems) { - await generateFlowLockInternal(folder, false, workspace, opts,undefined, undefined, useRawReqs); + await generateFlowLockInternal( + folder, + false, + workspace, + opts, + undefined, + undefined, + useRawReqs + ); } } } diff --git a/cli/src/commands/script/script.ts b/cli/src/commands/script/script.ts index 9c4171a97e..f719a008a3 100644 --- a/cli/src/commands/script/script.ts +++ b/cli/src/commands/script/script.ts @@ -29,7 +29,7 @@ import { parseMetadataFile, } from "../../utils/metadata.ts"; import { - LanguageWithRawReqsSupport, + LanguageWithRawReqsSupport, ScriptLanguage, inferContentTypeFromFilePath, languagesWithRawReqsSupport, @@ -114,8 +114,14 @@ export async function findResourceFile(path: string) { if (currentBranch) { // Add branch-specific candidates at the beginning (higher priority) - const branchSpecificJSON = specificItems.toBranchSpecificPath(contentBasePathJSON, currentBranch); - const branchSpecificYAML = specificItems.toBranchSpecificPath(contentBasePathYAML, currentBranch); + const branchSpecificJSON = specificItems.toBranchSpecificPath( + contentBasePathJSON, + currentBranch + ); + const branchSpecificYAML = specificItems.toBranchSpecificPath( + contentBasePathYAML, + currentBranch + ); candidates.unshift(branchSpecificJSON, branchSpecificYAML); } @@ -624,7 +630,7 @@ export const exts = [ ".nu", ".playbook.yml", ".java", - ".rb" + ".rb", // for related places search: ADD_NEW_LANG ]; @@ -727,7 +733,7 @@ async function run( if (opts.silent) { console.log(result); } else { - log.info(result); + log.info(JSON.stringify(result, null, 2)); } break; @@ -885,7 +891,10 @@ async function bootstrap( ); } -export type GlobalDeps = Map>; +export type GlobalDeps = Map< + LanguageWithRawReqsSupport, + Record +>; export async function findGlobalDeps(): Promise { var globalDeps: GlobalDeps = new Map(); @@ -895,9 +904,8 @@ export async function findGlobalDeps(): Promise { return ( !isDir && // Skip if the filename is not one of lockfile names - !(languagesWithRawReqsSupport.some( - lockfile => - p.endsWith(SEP + lockfile.rrFilename)) + !languagesWithRawReqsSupport.some((lockfile) => + p.endsWith(SEP + lockfile.rrFilename) ) ); }, els)) { @@ -906,9 +914,11 @@ export async function findGlobalDeps(): Promise { // Iterate over available languages to find which lockfile languagesWithRawReqsSupport.map((lock) => { - if (entry.path.endsWith(lock.rrFilename)){ + if (entry.path.endsWith(lock.rrFilename)) { const current = globalDeps.get(lock) ?? {}; - current[entry.path.substring(0, entry.path.length - lock.rrFilename.length)] = content; + current[ + entry.path.substring(0, entry.path.length - lock.rrFilename.length) + ] = content; globalDeps.set(lock, current); } }); diff --git a/cli/src/main.ts b/cli/src/main.ts index 30fad224ee..d76232d987 100644 --- a/cli/src/main.ts +++ b/cli/src/main.ts @@ -68,7 +68,7 @@ export { // } // }); -export const VERSION = "1.546.1"; +export const VERSION = "1.547.0"; export const WM_FORK_PREFIX = "wm-fork"; @@ -187,7 +187,7 @@ async function main() { log.setup({ handlers: { console: new log.ConsoleHandler(LOG_LEVEL, { - formatter: ({ msg }) => `${msg}`, + formatter: ({ msg }) => msg, useColors: isWin ? false : true, }), }, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5f2f72761b..0223522b34 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "windmill-components", - "version": "1.546.1", + "version": "1.547.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "windmill-components", - "version": "1.546.1", + "version": "1.547.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/frontend/package.json b/frontend/package.json index 4a8441970f..a18781ad8d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "windmill-components", - "version": "1.546.1", + "version": "1.547.0", "scripts": { "dev": "vite dev", "build": "vite build", diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 2c7125318d..bf00cdaf4c 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -9,7 +9,7 @@ {#each Object.keys(components['aggridinfinitecomponent'].initialData.configuration) as key (key)} @@ -194,10 +197,17 @@ bind:result bind:loading bind:runnableComponent - on:recompute={() => { - console.log('recompute') - clear() - }} + preventDefaultRefresh + overrideCallback={() => + new CancelablePromise(async (resolve) => { + if (ignoreFirst) { + ignoreFirst = false + resolve() + return + } + clear() + resolve() + })} {render} autoRefresh={true} allowConcurentRequests diff --git a/frontend/src/lib/components/apps/components/display/table/SyncColumnDefs.svelte b/frontend/src/lib/components/apps/components/display/table/SyncColumnDefs.svelte index 0b9977d948..9e45c0f770 100644 --- a/frontend/src/lib/components/apps/components/display/table/SyncColumnDefs.svelte +++ b/frontend/src/lib/components/apps/components/display/table/SyncColumnDefs.svelte @@ -118,11 +118,12 @@ } }) + let keys = $derived(Object.keys(result[0] ?? []).filter((x) => x !== '__index')) + async function syncColumns() { const gridItem = findGridItem($app, id) if (gridItem && result) { - const keys = Object.keys(result[0] ?? {}) ?? [] const conf = gridItem.data.configuration.columnDefs as ColumnDefsConfiguration const newColumns: WindmillColumnDef[] = keys.map((key) => ({ @@ -171,7 +172,7 @@
No columns definition found. Columns found in data:
- {#each Object.keys(result[0] ?? []) as key} + {#each keys as key} {key} {/each}
diff --git a/frontend/src/lib/components/apps/components/helpers/RefreshButton.svelte b/frontend/src/lib/components/apps/components/helpers/RefreshButton.svelte index fc25b2e382..14729e30fe 100644 --- a/frontend/src/lib/components/apps/components/helpers/RefreshButton.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RefreshButton.svelte @@ -32,13 +32,17 @@ color="light" size="xs2" btnClasses={twMerge(loading ? ' bg-blue-100 dark:bg-blue-400' : '', 'transition-all')} - on:click={() => { + on:click={(e) => { if (buttonHover && loading) { cancelCallbacks?.forEach((cb) => cb.cancel()) } else { cancelCallbacks = $runnableComponents[id]?.cb?.map((cb) => cb()) } }} + on:pointerdown={(e) => { + e.preventDefault() + e.stopPropagation() + }} iconOnly /> {#snippet text()} diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index 3b6eb73854..29780ce291 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -163,48 +163,8 @@ } } - // $: sendUserToast('args' + JSON.stringify(runnableInputValues) + Boolean(extraQueryParams) || args) - // $: console.log(runnableInputValues) let firstRefresh = true - // on:started={(e) => { - // console.log('started', e.detail) - // loading = true - // setJobId(e.detail) - // dispatch('started', e.detail) - // }} - // on:done={(e) => { - // lastJobId = e.detail.id - // setResult(e.detail.result, e.detail.id) - // loading = false - // dispatch('done', { id: e.detail?.id, result: e.detail?.result }) - // }} - // on:cancel={(e) => { - // let jobId = e.detail - // console.debug('cancel', jobId) - // let job = $jobsById[jobId] - // if (job && job.created_at && !job.duration_ms) { - // $jobsById[jobId] = { - // ...job, - // started_at: job.started_at ?? Date.now(), - // duration_ms: Date.now() - (job.started_at ?? job.created_at) - // } - // } - // dispatch('cancel', { id: e.detail }) - // }} - // on:running={(e) => { - // let jobId = e.detail - // let job = $jobsById[jobId] - // if (job && !job.started_at) { - // $jobsById[jobId] = { ...job, started_at: Date.now() } - // } - // }} - // on:doneError={(e) => { - // setResult({ error: e.detail.error }, e.detail.id) - // loading = false - // dispatch('doneError', { id: e.detail.id, result: e.detail.result }) - // }} - type RunnableCallback = { onDone?: (r: any) => void onCancel?: () => void diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte index 7f4dd7856a..2874422d2f 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte @@ -91,6 +91,7 @@ onSuccess?: (result: any) => void children?: import('svelte').Snippet nonRenderedPlaceholder?: import('svelte').Snippet + preventDefaultRefresh?: boolean } let { diff --git a/frontend/src/lib/components/common/layout/List.svelte b/frontend/src/lib/components/common/layout/List.svelte index 0d57af31cd..d1be35d1ce 100644 --- a/frontend/src/lib/components/common/layout/List.svelte +++ b/frontend/src/lib/components/common/layout/List.svelte @@ -1,10 +1,22 @@ + @@ -67,7 +69,7 @@ {#if selectedKind != 'preprocessor' && selectedKind != 'flow'} {/if} - (refreshCount += 1)} /> + (refreshCount.val += 1)} />
@@ -169,7 +171,7 @@ {preFilter} {small} {displayPath} - {refreshCount} + refreshCount={refreshCount.val} />
diff --git a/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte b/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte index feaa82a792..879dbed29c 100644 --- a/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte +++ b/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte @@ -2,7 +2,7 @@ let listHubIntegrationsCached = createCache( ({ kind }: { kind: HubScriptKind & string; refreshCount?: number }) => IntegrationService.listHubIntegrations({ kind }), - { initial: { kind: 'script', refreshCount: 0 } } + { initial: { kind: 'script', refreshCount: 0 }, invalidateMs: 1000 * 60 } ) let listHubScriptsCached = createCache( async ({ @@ -18,7 +18,10 @@ filter.length > 0 ? await ScriptService.queryHubScripts({ text: filter, limit: 40, kind }) : ((await ScriptService.getTopHubScripts({ limit: 40, kind, app: appFilter })).asks ?? []), - { initial: { filter: '', kind: 'script', appFilter: undefined, refreshCount: 0 } } + { + initial: { filter: '', kind: 'script', appFilter: undefined, refreshCount: 0 }, + invalidateMs: 1000 * 60 + } ) @@ -67,7 +70,15 @@ apps = $bindable([]), refreshCount = 0 }: Props = $props() - let allApps: string[] = [] + + let allApps: string[] = $state([]) + $effect(() => { + if (filter.length > 0) { + apps = Array.from(new Set(items?.map((x) => x.app) ?? [])).sort() + } else { + apps = allApps + } + }) async function getAllApps(filterKind: typeof kind) { try { @@ -75,11 +86,9 @@ allApps = (await listHubIntegrationsCached({ kind: filterKind, refreshCount })).map( (x) => x.name ) - apps = allApps } catch (err) { console.error('Hub is not available') allApps = [] - apps = [] hubNotAvailable = true } } @@ -93,7 +102,6 @@ hubScriptsFilteredPromise.refresh() }) $effect(() => { - // TODO: these should be derived ... loading = hubScriptsFilteredPromise.status === 'loading' hubNotAvailable = !!hubScriptsFilteredPromise.error const scripts = hubScriptsFilteredPromise.value @@ -113,11 +121,6 @@ summary: `${x.summary} (${x.app})` }) ) - if (filter.length > 0) { - apps = Array.from(new Set(mappedItems?.map((x) => x.app) ?? [])).sort() - } else { - apps = allApps - } items = appFilter ? mappedItems.filter((x) => x.app === appFilter) : mappedItems }) diff --git a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte index 2f6da65b47..7141c0f816 100644 --- a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte +++ b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte @@ -23,7 +23,8 @@ kind: 'script', isTemplate: undefined, refreshCount: 0 - } + }, + invalidateMs: 1000 * 60 } : {} ) @@ -52,7 +53,7 @@ let items = usePromise( async () => await loadItemsCached({ workspace: $workspaceStore!, kind, isTemplate, refreshCount }), - { loadInit: false } + { loadInit: false, clearValueOnRefresh: false } ) let filteredItems: (Item & { marked?: string })[] | undefined = $state(undefined) diff --git a/frontend/src/lib/components/home/ItemsList.svelte b/frontend/src/lib/components/home/ItemsList.svelte index 94ace3e2b4..af3b1e944b 100644 --- a/frontend/src/lib/components/home/ItemsList.svelte +++ b/frontend/src/lib/components/home/ItemsList.svelte @@ -56,6 +56,7 @@ time?: number starred?: boolean has_draft?: boolean + hash?: string } type TableScript = TableItem @@ -553,7 +554,7 @@ /> {:else}
- {#each (items ?? []).slice(0, nbDisplayed) as item (item.type + '/' + item.path)} + {#each (items ?? []).slice(0, nbDisplayed) as item (item.type + '/' + item.path + (item.hash ? '/' + item.hash : ''))} loadScripts(includeWithoutMain)} diff --git a/frontend/src/lib/components/triggers/websocket/WebsocketTriggerEditorInner.svelte b/frontend/src/lib/components/triggers/websocket/WebsocketTriggerEditorInner.svelte index 19c156fc8c..92f4778cc5 100644 --- a/frontend/src/lib/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +++ b/frontend/src/lib/components/triggers/websocket/WebsocketTriggerEditorInner.svelte @@ -92,6 +92,7 @@ let initial_messages: WebsocketTriggerInitialMessage[] = $state([]) let url_runnable_args: Record | undefined = $state({}) let can_return_message = $state(false) + let can_return_error_result = $state(false) let dirtyPath = $state(false) let can_write = $state(true) let drawerLoading = $state(true) @@ -128,6 +129,12 @@ is_flow = itemKind === 'flow' }) + $effect(() => { + if (!can_return_message) { + can_return_error_result = false + } + }) + export async function openEdit( ePath: string, isFlow: boolean, @@ -183,6 +190,7 @@ url_runnable_args = defaultValues?.url_runnable_args ?? {} dirtyPath = false can_return_message = false + can_return_error_result = false error_handler_path = defaultValues?.error_handler_path ?? undefined error_handler_args = defaultValues?.error_handler_args ?? {} retry = defaultValues?.retry ?? undefined @@ -205,6 +213,7 @@ initial_messages = cfg?.initial_messages ?? [] url_runnable_args = cfg?.url_runnable_args can_return_message = cfg?.can_return_message + can_return_error_result = cfg?.can_return_error_result can_write = canWrite(path, cfg?.extra_perms, $userStore) error_handler_path = cfg?.error_handler_path error_handler_args = cfg?.error_handler_args ?? {} @@ -223,6 +232,7 @@ initial_messages, url_runnable_args, can_return_message, + can_return_error_result, enabled, error_handler_path, error_handler_args, @@ -463,6 +473,19 @@ }} disabled={!can_write} /> + + { + can_return_error_result = !can_return_error_result + }} + options={{ + right: 'Send result on error', + rightTooltip: + 'Allows the runnable result to be sent as a message to the WebSocket server if the result is a non-null error.' + }} + disabled={!can_write || !can_return_message} + /> , T, InitialKeys extends Keys = Keys>( compute: (keys: Keys) => T, - params?: { maxSize?: number; initial?: InitialKeys } + params?: { maxSize?: number; initial?: InitialKeys; invalidateMs?: number } ): (keys: Keys) => T { - let cache = new Map() + let cache = new Map() const maxSize = params?.maxSize ?? 15 if (params?.initial) { let key = JSON.stringify(params.initial, Object.keys(params.initial).sort()) let value = compute(params.initial) - cache.set(key, value) + cache.set(key, { value, timestamp: Date.now() }) } return (keys: Keys) => { + if (typeof params?.invalidateMs === 'number') { + for (const [key, entry] of cache.entries()) { + if (Date.now() - entry.timestamp > params.invalidateMs) { + cache.delete(key) + } + } + } + let key = JSON.stringify(keys, Object.keys(keys).sort()) if (!cache.get(key)) { let value = compute(keys) - cache.set(key, value) + cache.set(key, { value, timestamp: Date.now() }) if (cache.size > maxSize) { // remove the oldest entry (first inserted) @@ -1610,6 +1618,6 @@ export function createCache, T, InitialKeys ext cache.delete(oldestKey) } } - return cache.get(key)! + return cache.get(key)!.value } } diff --git a/lsp/Pipfile b/lsp/Pipfile index 47bc3d54a1..e06b2358bb 100644 --- a/lsp/Pipfile +++ b/lsp/Pipfile @@ -4,8 +4,8 @@ verify_ssl = true name = "pypi" [packages] -wmill = ">=1.546.1" -wmill_pg = ">=1.546.1" +wmill = ">=1.547.0" +wmill_pg = ">=1.547.0" sendgrid = "*" mysql-connector-python = "*" pymongo = "*" diff --git a/openflow.openapi.yaml b/openflow.openapi.yaml index 37d235675c..39d349d3f0 100644 --- a/openflow.openapi.yaml +++ b/openflow.openapi.yaml @@ -1,7 +1,7 @@ openapi: "3.0.3" info: - version: 1.546.1 + version: 1.547.0 title: OpenFlow Spec contact: name: Ruben Fiszel diff --git a/powershell-client/WindmillClient/WindmillClient.psd1 b/powershell-client/WindmillClient/WindmillClient.psd1 index 8fa3a67310..21aafa7611 100644 --- a/powershell-client/WindmillClient/WindmillClient.psd1 +++ b/powershell-client/WindmillClient/WindmillClient.psd1 @@ -12,7 +12,7 @@ RootModule = 'WindmillClient.psm1' # Version number of this module. - ModuleVersion = '1.546.1' + ModuleVersion = '1.547.0' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/python-client/wmill/pyproject.toml b/python-client/wmill/pyproject.toml index 44e4dac416..042a24759d 100644 --- a/python-client/wmill/pyproject.toml +++ b/python-client/wmill/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "wmill" -version = "1.546.1" +version = "1.547.0" description = "A client library for accessing Windmill server wrapping the Windmill client API" license = "Apache-2.0" homepage = "https://windmill.dev" diff --git a/python-client/wmill_pg/pyproject.toml b/python-client/wmill_pg/pyproject.toml index 811d109887..773c81c8a8 100644 --- a/python-client/wmill_pg/pyproject.toml +++ b/python-client/wmill_pg/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "wmill-pg" -version = "1.546.1" +version = "1.547.0" description = "An extension client for the wmill client library focused on pg" license = "Apache-2.0" homepage = "https://windmill.dev" diff --git a/typescript-client/jsr.json b/typescript-client/jsr.json index d02e7a16e1..949477ce4b 100644 --- a/typescript-client/jsr.json +++ b/typescript-client/jsr.json @@ -1,6 +1,6 @@ { "name": "@windmill/windmill", - "version": "1.546.1", + "version": "1.547.0", "exports": "./src/index.ts", "publish": { "exclude": ["!src", "./s3Types.ts", "./client.ts"] diff --git a/typescript-client/package.json b/typescript-client/package.json index f4a3fe75d4..feac8d59a6 100644 --- a/typescript-client/package.json +++ b/typescript-client/package.json @@ -1,7 +1,7 @@ { "name": "windmill-client", "description": "Windmill SDK client for browsers and Node.js", - "version": "1.546.1", + "version": "1.547.0", "author": "Ruben Fiszel", "license": "Apache 2.0", "devDependencies": { diff --git a/version.txt b/version.txt index 078cbb62ee..bbfc94b167 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.546.1 +1.547.0