Compare commits

...
25 Commits
Author SHA1 Message Date
Pyranota e56fa3909e Remove --dir flag
EE repos are handled either manually or with --auto-substitute flag
2025-01-24 18:49:43 +03:00
Pyranota 44b623ca6d Update docker.nu 2025-01-24 18:46:04 +03:00
Pyranota ca34f741bc Merge branch 'docker.nu' of github.com:windmill-labs/windmill into docker.nu 2025-01-24 17:42:07 +03:00
Ruben Fiszel 669a1ff8e6 fix: improve workspace specific tags behavior 2025-01-21 18:15:34 +01:00
Ruben Fiszel e81c2c983d fix: improve workspace specific tags behavior 2025-01-21 16:24:50 +01:00
Lucas Abel ba711c48df backend: always prioritize flow steps (#5108)
When a flow start, his flow steps have lower priority than already scheduled jobs, hence steps are only executed when the queue is drained which considerably increase flow execution time when queue size is significant.
This add a very low priority to flow steps in order to prioritize finishing a started flow over new jobs.
2025-01-21 09:27:40 +01:00
Ruben Fiszelandrubenfiszel 2b0c55b32c chore(main): release 1.447.6 (#5098)
* chore(main): release 1.447.6

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2025-01-21 09:06:41 +01:00
Ruben Fiszel ffc156c4a6 fix table actions job preview 2025-01-21 01:52:08 +01:00
pyranota 8eb5e72ccd fix(python): Replace Inf with null (#5099) 2025-01-20 19:38:35 +01:00
pyranota 5831822afe fix: improve uv dependency install reliability with an atomic success file
* Revert solution with Mutex

* Implement valid.windmill logic

* Remove unused import

* valid.windmill -> .valid.windmill

Just like .lock

* Dont delete wheels if cancelled/failed

Now we dont clean up requirement folder if it was failed.

This way we can fully utilize uv's flock system.

Also if we left wheel dir, but it was partially filled (resulting to invalid wheel)
we use --reinstall flag in order to overwrite any content of wheels

* Add comment

* Add --reinstall to nsjail
2025-01-20 16:21:10 +01:00
Ruben Fiszel 99b0193a72 fix cli compile 2025-01-17 23:22:59 +01:00
Ruben Fiszelandrubenfiszel 4301a1758f chore(main): release 1.447.5 (#5082)
* chore(main): release 1.447.5

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2025-01-17 20:45:05 +01:00
wendrul 298aaaefa3 fix: c# on windows, oracledb test connection, cli for C# and Oracle DB (#5090)
* Fix c# on windows

* Fix test connection on oracledb

* Add csharp and oracledb to CLI

* Fix missing extensions

* Build wasm for cli
2025-01-17 20:16:22 +01:00
Alexander Petric 6f469ac9e0 rhel image build workaround (#5091)
* RHEL Dockerfile / no chef

* Update Dockerfile

* Update Dockerfile

* Update build-publish-rh-image.yml
2025-01-17 19:50:23 +01:00
Ruben Fiszel 0d153a0a2d fix: fix workspace specific custom tags 2025-01-17 19:48:38 +01:00
HugoCasa 501c44b3a1 fix(frontend): webhook/route payload from args (#5088) 2025-01-17 18:59:30 +01:00
HugoCasa 64f4958774 fix(frontend): empty arg initial height (#5089) 2025-01-17 18:59:21 +01:00
HugoCasa d234431b7e nits cloud team plan settings (#5086) 2025-01-17 16:48:19 +01:00
Ruben Fiszel 854febdafd fix: require preexisting user option for auth correctly saved 2025-01-17 15:22:22 +01:00
Lucas Abel bc92cc0d15 build: update nix flake lock (#5083) 2025-01-17 15:18:16 +01:00
HugoCasa d1794c9811 fix(frontend): input autosize on default value (#5080) 2025-01-17 14:12:11 +01:00
HugoCasa 742d04df38 fix: preprocessor script kind option (#5081)
* fix: preprocessor script kind option

* oups

* oups
2025-01-17 14:10:39 +01:00
HugoCasa 1f53ded622 team plans billing threshold alert (#5078)
* team plans billing threshold alert

* nits

* tmp ee ref

* update ee ref
2025-01-17 14:06:47 +01:00
Ruben Fiszel 7f18d84edc simplify worker loading logic 2025-01-17 11:27:56 +01:00
pyranota cd6b35dfae DevEx: Implement docker.nu helper
------------------------------------
 Build and Test docker images locally
                run:
        docker/docker.nu --help
 ------------------------------------
2024-12-12 16:13:21 +01:00
80 changed files with 2099 additions and 552 deletions
+12 -12
View File
@@ -97,16 +97,16 @@ jobs:
image: ${{ steps.meta-ee-public.outputs.tags}}-amd64
path: "/windmill/target/release/windmill"
- uses: shrink/actions-docker-extract@v3
id: extract-ee-arm64
with:
image: ${{ steps.meta-ee-public.outputs.tags}}-arm64
path: "/windmill/target/release/windmill"
# - uses: shrink/actions-docker-extract@v3
# id: extract-ee-arm64
# with:
# image: ${{ steps.meta-ee-public.outputs.tags}}-arm64
# path: "/windmill/target/release/windmill"
- name: Rename binary with corresponding architecture
run: |
mv "${{ steps.extract-ee-amd64.outputs.destination }}/windmill" "${{ steps.extract-ee-amd64.outputs.destination }}/windmill-ee-amd64-rhel9"
mv "${{ steps.extract-ee-arm64.outputs.destination }}/windmill" "${{ steps.extract-ee-arm64.outputs.destination }}/windmill-ee-arm64-rhel9"
# mv "${{ steps.extract-ee-arm64.outputs.destination }}/windmill" "${{ steps.extract-ee-arm64.outputs.destination }}/windmill-ee-arm64-rhel9"
- uses: actions/upload-artifact@v4
with:
@@ -115,12 +115,12 @@ jobs:
${{ steps.extract-ee-amd64.outputs.destination
}}/windmill-ee-amd64-rhel9
- uses: actions/upload-artifact@v4
with:
name: RHEL9-arm64 build
path:
${{ steps.extract-ee-arm64.outputs.destination
}}/windmill-ee-arm64-rhel9
# - uses: actions/upload-artifact@v4
# with:
# name: RHEL9-arm64 build
# path:
# ${{ steps.extract-ee-arm64.outputs.destination
# }}/windmill-ee-arm64-rhel9
# - name: Attach binary to release
# uses: softprops/action-gh-release@v2
+21
View File
@@ -1,5 +1,26 @@
# Changelog
## [1.447.6](https://github.com/windmill-labs/windmill/compare/v1.447.5...v1.447.6) (2025-01-21)
### Bug Fixes
* improve uv dependency install reliability with an atomic success file ([5831822](https://github.com/windmill-labs/windmill/commit/5831822afeb9919b8af3dc6ce60100736cab9d01))
* **python:** Replace Inf with null ([#5099](https://github.com/windmill-labs/windmill/issues/5099)) ([8eb5e72](https://github.com/windmill-labs/windmill/commit/8eb5e72ccdcc037d94209632f3e64742c809fd7e))
## [1.447.5](https://github.com/windmill-labs/windmill/compare/v1.447.4...v1.447.5) (2025-01-17)
### Bug Fixes
* c# on windows, oracledb test connection, cli for C# and Oracle DB ([#5090](https://github.com/windmill-labs/windmill/issues/5090)) ([298aaae](https://github.com/windmill-labs/windmill/commit/298aaaefa398234473a54cbc15756ee2d6b0e68c))
* fix workspace specific custom tags ([0d153a0](https://github.com/windmill-labs/windmill/commit/0d153a0a2d3954c702d41afeb3f4d74152b071f0))
* **frontend:** empty arg initial height ([#5089](https://github.com/windmill-labs/windmill/issues/5089)) ([64f4958](https://github.com/windmill-labs/windmill/commit/64f4958774a8259c3a28c394da6ab599ac9d43bb))
* **frontend:** input autosize on default value ([#5080](https://github.com/windmill-labs/windmill/issues/5080)) ([d1794c9](https://github.com/windmill-labs/windmill/commit/d1794c9811c1c944a9c68d2e1b8f0bb50db4e1f8))
* **frontend:** webhook/route payload from args ([#5088](https://github.com/windmill-labs/windmill/issues/5088)) ([501c44b](https://github.com/windmill-labs/windmill/commit/501c44b3a1f38256bc7b304109ebbaa45678c792))
* preprocessor script kind option ([#5081](https://github.com/windmill-labs/windmill/issues/5081)) ([742d04d](https://github.com/windmill-labs/windmill/commit/742d04df38b240f12c58a0785014034f55409eab))
* require preexisting user option for auth correctly saved ([854febd](https://github.com/windmill-labs/windmill/commit/854febdafd48f114b5943de77893d80f437310ba))
## [1.447.4](https://github.com/windmill-labs/windmill/compare/v1.447.3...v1.447.4) (2025-01-16)
+2 -1
View File
@@ -5,4 +5,5 @@ oauth2.json
tracing.folded
heaptrack*
index/
windmill-api/openapi-*.*
windmill-api/openapi-*.*
.docker.nu/
@@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO cloud_workspace_settings (workspace_id, threshold_alert_amount) VALUES ($1, $2) ON CONFLICT (workspace_id) DO UPDATE SET threshold_alert_amount = $2, last_alert_sent = NULL",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Int4"
]
},
"nullable": []
},
"hash": "c4e0f3eab227a798d9cd7478db50a7c1a588e69c2c8d9a1def9276ba326453d2"
}
@@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT threshold_alert_amount, last_alert_sent FROM cloud_workspace_settings WHERE workspace_id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "threshold_alert_amount",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "last_alert_sent",
"type_info": "Timestamp"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
true,
true
]
},
"hash": "f74589aaa72d0eb9f44157cc60eb121e63a7f31ed849834bb8ac9e8c726e81f1"
}
@@ -1,30 +1,35 @@
{
"db_name": "PostgreSQL",
"query": "SELECT premium, usage.usage as \"usage?\", workspace_settings.customer_id, workspace_settings.plan, workspace_settings.automatic_billing FROM workspace LEFT JOIN workspace_settings ON workspace_settings.workspace_id = $1 LEFT JOIN usage ON usage.id = $1 AND month_ = EXTRACT(YEAR FROM current_date) * 12 + EXTRACT(MONTH FROM current_date) AND usage.is_workspace IS true WHERE workspace.id = $1",
"query": "SELECT owner, premium, usage.usage as \"usage?\", workspace_settings.customer_id, workspace_settings.plan, workspace_settings.automatic_billing FROM workspace LEFT JOIN workspace_settings ON workspace_settings.workspace_id = $1 LEFT JOIN usage ON usage.id = $1 AND month_ = EXTRACT(YEAR FROM current_date) * 12 + EXTRACT(MONTH FROM current_date) AND usage.is_workspace IS true WHERE workspace.id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "owner",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "premium",
"type_info": "Bool"
},
{
"ordinal": 1,
"ordinal": 2,
"name": "usage?",
"type_info": "Int4"
},
{
"ordinal": 2,
"ordinal": 3,
"name": "customer_id",
"type_info": "Varchar"
},
{
"ordinal": 3,
"ordinal": 4,
"name": "plan",
"type_info": "Varchar"
},
{
"ordinal": 4,
"ordinal": 5,
"name": "automatic_billing",
"type_info": "Bool"
}
@@ -35,6 +40,7 @@
]
},
"nullable": [
false,
false,
false,
true,
@@ -42,5 +48,5 @@
false
]
},
"hash": "49a8fe5c538d8fc26f6d8ece5b30dd02a128f571039714e61525e2bb86591d93"
"hash": "f8f893fb4f6f8c16bffb233a585df0b8c007c24993979fdc013aa57583905f50"
}
+87 -106
View File
@@ -360,7 +360,7 @@ dependencies = [
"arrow-schema",
"chrono",
"half",
"indexmap 2.7.0",
"indexmap 2.7.1",
"lexical-core",
"num",
"serde",
@@ -1160,24 +1160,6 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "bindgen"
version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
dependencies = [
"bitflags 2.8.0",
"cexpr",
"clang-sys",
"itertools 0.13.0",
"proc-macro2",
"quote",
"regex",
"rustc-hash 2.1.0",
"shlex",
"syn 2.0.96",
]
[[package]]
name = "bit-set"
version = "0.5.3"
@@ -1332,9 +1314,9 @@ dependencies = [
[[package]]
name = "borsh"
version = "1.5.4"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb65153674e51d3a42c8f27b05b9508cea85edfaade8aa46bc8fc18cecdfef3"
checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc"
dependencies = [
"borsh-derive",
"cfg_aliases",
@@ -1342,9 +1324,9 @@ dependencies = [
[[package]]
name = "borsh-derive"
version = "1.5.4"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a396e17ad94059c650db3d253bb6e25927f1eb462eede7e7a153bb6e75dce0a7"
checksum = "f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487"
dependencies = [
"once_cell",
"proc-macro-crate",
@@ -1562,7 +1544,7 @@ version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e11c675378efb449ed3ce8de78d75d0d80542fc98487c26aba28eb3b82feac72"
dependencies = [
"semver 1.0.24",
"semver 1.0.25",
"serde",
"toml 0.7.8",
"url",
@@ -1570,9 +1552,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.9"
version = "1.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
dependencies = [
"jobserver",
"libc",
@@ -1634,9 +1616,9 @@ dependencies = [
[[package]]
name = "chrono-tz"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6dd8046d00723a59a2f8c5f295c515b9bb9a331ee4f8f3d4dd49e428acd3b6"
checksum = "9c6ac4f2c0bf0f44e9161aec9675e1050aa4a530663c4a9e37e108fa948bca9f"
dependencies = [
"chrono",
"chrono-tz-build 0.4.0",
@@ -1686,9 +1668,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.26"
version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1696,9 +1678,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.26"
version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
dependencies = [
"anstream",
"anstyle",
@@ -2267,7 +2249,7 @@ dependencies = [
"glob",
"half",
"hashbrown 0.14.5",
"indexmap 2.7.0",
"indexmap 2.7.1",
"itertools 0.12.1",
"log",
"num_cpus",
@@ -2436,7 +2418,7 @@ dependencies = [
"datafusion-expr",
"datafusion-physical-expr",
"hashbrown 0.14.5",
"indexmap 2.7.0",
"indexmap 2.7.1",
"itertools 0.12.1",
"log",
"regex-syntax 0.8.5",
@@ -2465,7 +2447,7 @@ dependencies = [
"half",
"hashbrown 0.14.5",
"hex",
"indexmap 2.7.0",
"indexmap 2.7.1",
"itertools 0.12.1",
"log",
"paste",
@@ -2509,7 +2491,7 @@ dependencies = [
"futures",
"half",
"hashbrown 0.14.5",
"indexmap 2.7.0",
"indexmap 2.7.1",
"itertools 0.12.1",
"log",
"once_cell",
@@ -2618,7 +2600,7 @@ dependencies = [
"deno_ops",
"deno_unsync",
"futures",
"indexmap 2.7.0",
"indexmap 2.7.1",
"libc",
"memoffset",
"parking_lot",
@@ -2679,9 +2661,9 @@ dependencies = [
[[package]]
name = "deno_media_type"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a417f8bd3f1074185c4c8ccb6ea6261ae173781596cc358e68ad07aaac11009d"
checksum = "577fe2bbe04f3e9b1b7c6fac6a75101a9fbd611c50a6b68789e69f4d63dcb2b4"
dependencies = [
"data-url",
"serde",
@@ -3208,18 +3190,18 @@ dependencies = [
[[package]]
name = "enumflags2"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147"
dependencies = [
"enumflags2_derive",
]
[[package]]
name = "enumflags2_derive"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79"
dependencies = [
"proc-macro2",
"quote",
@@ -3883,7 +3865,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap 2.7.0",
"indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -3902,7 +3884,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.2.0",
"indexmap 2.7.0",
"indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -4571,9 +4553,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.7.0"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
@@ -4631,9 +4613,9 @@ dependencies = [
[[package]]
name = "ipnet"
version = "2.10.1"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "is-macro"
@@ -4742,7 +4724,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
]
[[package]]
@@ -5373,12 +5355,11 @@ dependencies = [
[[package]]
name = "mysql_common"
version = "0.34.0"
version = "0.34.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed90d09e2ca55764bf65030ff5a387fdee42282fe3b89a38fa8f96a809882bc1"
checksum = "34a9141e735d5bb02414a7ac03add09522466d4db65bdd827069f76ae0850e58"
dependencies = [
"base64 0.22.1",
"bindgen 0.71.1",
"bitflags 2.8.0",
"btoi",
"byteorder",
@@ -5622,9 +5603,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "oauth2"
version = "5.0.0-rc.1"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d385da3c602d29036d2f70beed71c36604df7570be17fed4c5b839616785bf"
checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d"
dependencies = [
"base64 0.22.1",
"chrono",
@@ -5741,9 +5722,9 @@ dependencies = [
[[package]]
name = "openidconnect"
version = "4.0.0-rc.1"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a93a50789d0b649986bfb104cdef97736ca072d579ec88496d5c6f9abed0ea85"
checksum = "6dd50d4a5e7730e754f94d977efe61f611aadd3131f6a2b464f6e3a4167e8ef7"
dependencies = [
"base64 0.21.7",
"chrono",
@@ -6139,7 +6120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
"indexmap 2.7.0",
"indexmap 2.7.1",
]
[[package]]
@@ -7271,7 +7252,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver 1.0.24",
"semver 1.0.25",
]
[[package]]
@@ -7675,9 +7656,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
dependencies = [
"serde",
]
@@ -7759,11 +7740,11 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.135"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
"itoa",
"memchr",
"ryu",
@@ -7887,7 +7868,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.7.0",
"indexmap 2.7.1",
"serde",
"serde_derive",
"serde_json",
@@ -7913,7 +7894,7 @@ version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
"itoa",
"ryu",
"serde",
@@ -8289,7 +8270,7 @@ dependencies = [
"futures-util",
"hashbrown 0.15.2",
"hashlink",
"indexmap 2.7.0",
"indexmap 2.7.1",
"log",
"memchr",
"once_cell",
@@ -8658,7 +8639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000"
dependencies = [
"anyhow",
"indexmap 2.7.0",
"indexmap 2.7.1",
"serde",
"serde_json",
"swc_cached",
@@ -8770,7 +8751,7 @@ checksum = "65f21494e75d0bd8ef42010b47cabab9caaed8f2207570e809f6f4eb51a710d1"
dependencies = [
"better_scoped_tls",
"bitflags 2.8.0",
"indexmap 2.7.0",
"indexmap 2.7.1",
"once_cell",
"phf",
"rustc-hash 1.1.0",
@@ -8839,7 +8820,7 @@ checksum = "76c76d8b9792ce51401d38da0fa62158d61f6d80d16d68fe5b03ce4bf5fba383"
dependencies = [
"base64 0.21.7",
"dashmap",
"indexmap 2.7.0",
"indexmap 2.7.1",
"once_cell",
"serde",
"sha1",
@@ -8879,7 +8860,7 @@ version = "0.134.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029eec7dd485923a75b5a45befd04510288870250270292fc2c1b3a9e7547408"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
"num_cpus",
"once_cell",
"rustc-hash 1.1.0",
@@ -9703,7 +9684,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
"serde",
"serde_spanned",
"toml_datetime",
@@ -9716,7 +9697,7 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap 2.7.0",
"indexmap 2.7.1",
"serde",
"serde_spanned",
"toml_datetime",
@@ -9765,7 +9746,7 @@ dependencies = [
"home",
"once_cell",
"regex",
"semver 1.0.24",
"semver 1.0.25",
"walkdir",
]
@@ -10453,9 +10434,9 @@ dependencies = [
[[package]]
name = "valuable"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
@@ -10743,7 +10724,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windmill"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"axum",
@@ -10784,7 +10765,7 @@ dependencies = [
[[package]]
name = "windmill-api"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"argon2",
@@ -10802,7 +10783,7 @@ dependencies = [
"candle-nn",
"candle-transformers",
"chrono",
"chrono-tz 0.10.0",
"chrono-tz 0.10.1",
"const_format",
"cookie 0.17.0",
"cron",
@@ -10871,7 +10852,7 @@ dependencies = [
[[package]]
name = "windmill-api-client"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"base64 0.22.1",
"chrono",
@@ -10889,7 +10870,7 @@ dependencies = [
[[package]]
name = "windmill-audit"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"chrono",
"serde",
@@ -10902,7 +10883,7 @@ dependencies = [
[[package]]
name = "windmill-autoscaling"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"serde",
@@ -10916,7 +10897,7 @@ dependencies = [
[[package]]
name = "windmill-common"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"async-stream",
@@ -10925,7 +10906,7 @@ dependencies = [
"axum",
"bytes",
"chrono",
"chrono-tz 0.10.0",
"chrono-tz 0.10.1",
"const_format",
"crc",
"cron",
@@ -10937,7 +10918,7 @@ dependencies = [
"hex",
"hmac",
"hyper 1.5.2",
"indexmap 2.7.0",
"indexmap 2.7.1",
"itertools 0.14.0",
"lazy_static",
"magic-crypt",
@@ -10954,7 +10935,7 @@ dependencies = [
"rand 0.8.5",
"regex",
"reqwest 0.12.9",
"semver 1.0.24",
"semver 1.0.25",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -10975,7 +10956,7 @@ dependencies = [
[[package]]
name = "windmill-git-sync"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"regex",
"serde",
@@ -10989,7 +10970,7 @@ dependencies = [
[[package]]
name = "windmill-indexer"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"bytes",
@@ -11012,7 +10993,7 @@ dependencies = [
[[package]]
name = "windmill-macros"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"itertools 0.14.0",
"lazy_static",
@@ -11024,7 +11005,7 @@ dependencies = [
[[package]]
name = "windmill-parser"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"convert_case 0.6.0",
"serde",
@@ -11033,7 +11014,7 @@ dependencies = [
[[package]]
name = "windmill-parser-bash"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"lazy_static",
@@ -11045,7 +11026,7 @@ dependencies = [
[[package]]
name = "windmill-parser-csharp"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"serde_json",
@@ -11057,7 +11038,7 @@ dependencies = [
[[package]]
name = "windmill-parser-go"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"gosyn",
@@ -11069,7 +11050,7 @@ dependencies = [
[[package]]
name = "windmill-parser-graphql"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"lazy_static",
@@ -11081,7 +11062,7 @@ dependencies = [
[[package]]
name = "windmill-parser-php"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"itertools 0.14.0",
@@ -11092,7 +11073,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"itertools 0.14.0",
@@ -11103,7 +11084,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py-imports"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"async-recursion",
@@ -11121,7 +11102,7 @@ dependencies = [
[[package]]
name = "windmill-parser-rust"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@@ -11138,7 +11119,7 @@ dependencies = [
[[package]]
name = "windmill-parser-sql"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"lazy_static",
@@ -11150,7 +11131,7 @@ dependencies = [
[[package]]
name = "windmill-parser-ts"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"lazy_static",
@@ -11168,7 +11149,7 @@ dependencies = [
[[package]]
name = "windmill-parser-wasm"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"getrandom 0.2.15",
@@ -11190,7 +11171,7 @@ dependencies = [
[[package]]
name = "windmill-parser-yaml"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"serde_json",
@@ -11200,7 +11181,7 @@ dependencies = [
[[package]]
name = "windmill-queue"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"async-recursion",
@@ -11208,7 +11189,7 @@ dependencies = [
"backon",
"bigdecimal",
"chrono",
"chrono-tz 0.10.0",
"chrono-tz 0.10.1",
"cron",
"futures",
"futures-core",
@@ -11234,7 +11215,7 @@ dependencies = [
[[package]]
name = "windmill-sql-datatype-parser-wasm"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"wasm-bindgen",
"wasm-bindgen-test",
@@ -11244,7 +11225,7 @@ dependencies = [
[[package]]
name = "windmill-worker"
version = "1.447.4"
version = "1.447.6"
dependencies = [
"anyhow",
"async-recursion",
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "windmill"
version = "1.447.4"
version = "1.447.6"
authors.workspace = true
edition.workspace = true
@@ -30,7 +30,7 @@ members = [
]
[workspace.package]
version = "1.447.4"
version = "1.447.6"
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
edition = "2021"
+1 -1
View File
@@ -1 +1 @@
fb5e285c316f10fa2188318585573c7e85999784
ddcfdfc18a9833a5fc4e62ad62a265ef1e06a0aa
@@ -0,0 +1 @@
DROP TABLE IF EXISTS cloud_workspace_settings;
@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS cloud_workspace_settings (
workspace_id VARCHAR(50) NOT NULL,
threshold_alert_amount INT NULL,
last_alert_sent TIMESTAMP NULL,
PRIMARY KEY (workspace_id),
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADE
)
+66 -4
View File
@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.447.4
version: 1.447.6
title: Windmill API
contact:
@@ -1812,10 +1812,12 @@ paths:
type: number
automatic_billing:
type: boolean
owner:
type: string
required:
- premium
- automatic_billing
- owner
/w/{workspace}/workspaces/set_automatic_billing:
post:
summary: set automatic billing
@@ -1847,6 +1849,55 @@ paths:
schema:
type: string
/w/{workspace}/workspaces/threshold_alert:
get:
summary: get threshold alert info
operationId: getThresholdAlert
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
responses:
"200":
description: status
content:
application/json:
schema:
type: object
properties:
threshold_alert_amount:
type: number
last_alert_sent:
type: string
format: date-time
post:
summary: set threshold alert info
operationId: setThresholdAlert
tags:
- workspace
parameters:
- $ref: "#/components/parameters/WorkspaceId"
requestBody:
description: threshold alert info
required: true
content:
application/json:
schema:
type: object
properties:
threshold_alert_amount:
type: number
responses:
"200":
description: status
content:
text/plain:
schema:
type: string
/w/{workspace}/workspaces/edit_slack_command:
post:
summary: edit slack command
@@ -4246,6 +4297,17 @@ paths:
operationId: getCustomTags
tags:
- worker
parameters:
- name: workspace
in: query
schema:
type: string
required: false
- name: show_workspace_restriction
in: query
schema:
type: boolean
required: false
responses:
"200":
description: list of custom tags
@@ -11003,7 +11065,7 @@ components:
]
kind:
type: string
enum: [script, failure, trigger, command, approval]
enum: [script, failure, trigger, command, approval, preprocessor]
starred:
type: boolean
tag:
@@ -11109,7 +11171,7 @@ components:
]
kind:
type: string
enum: [script, failure, trigger, command, approval]
enum: [script, failure, trigger, command, approval, preprocessor]
tag:
type: string
draft_only:
+20 -8
View File
@@ -28,6 +28,7 @@ use axum::{
Json, Router,
};
use hyper::StatusCode;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use serde_json::json;
use serde_json::value::RawValue;
@@ -238,7 +239,19 @@ async fn list_scripts(
.limit(per_page)
.clone();
if !lq.include_without_main.unwrap_or(false) || authed.is_operator {
let lowercased_kinds: Option<Vec<String>> = lq
.kinds
.map(|x| x.split(",").map(&str::to_lowercase).collect());
if (!lq.include_without_main.unwrap_or(false)
&& lowercased_kinds
.as_ref()
.map(|x| !x.contains(&"preprocessor".to_string()))
.unwrap_or(true))
|| authed.is_operator
{
// only include scripts that have a main function
// do not hide scripts without main if preprocessor is in the kinds
sqlb.and_where("o.no_main_func IS NOT TRUE");
}
@@ -278,14 +291,13 @@ async fn list_scripts(
if let Some(it) = &lq.is_template {
sqlb.and_where_eq("is_template", it);
}
if let Some(kinds_val) = &lq.kinds {
let lowercased_kinds: Vec<String> = kinds_val
.split(",")
.map(&str::to_lowercase)
if let Some(lowercased_kinds) = lowercased_kinds {
let safe_kinds = lowercased_kinds
.into_iter()
.map(sql_builder::quote)
.collect();
if lowercased_kinds.len() > 0 {
sqlb.and_where_in("kind", lowercased_kinds.as_slice());
.collect_vec();
if safe_kinds.len() > 0 {
sqlb.and_where_in("kind", safe_kinds.as_slice());
}
}
if lq.starred_only.unwrap_or(false) {
+43 -3
View File
@@ -19,7 +19,7 @@ use windmill_common::{
db::UserDB,
error::JsonResult,
utils::{paginate, Pagination},
worker::{ALL_TAGS, DEFAULT_TAGS, DEFAULT_TAGS_PER_WORKSPACE},
worker::{ALL_TAGS, CUSTOM_TAGS_PER_WORKSPACE, DEFAULT_TAGS, DEFAULT_TAGS_PER_WORKSPACE},
DB,
};
@@ -133,8 +133,48 @@ async fn exists_worker_with_tag(
Ok(Json(row.exists.unwrap_or(false)))
}
async fn get_custom_tags() -> Json<Vec<String>> {
Json(ALL_TAGS.read().await.clone().into())
#[derive(Deserialize)]
struct CustomTagQuery {
workspace: Option<String>,
show_workspace_restriction: Option<bool>,
}
async fn get_custom_tags(Query(query): Query<CustomTagQuery>) -> JsonResult<Vec<String>> {
if query.show_workspace_restriction.is_some_and(|x| x) && query.workspace.is_some() {
return Err(windmill_common::error::Error::BadRequest(
"Cannot use both workspace and show_workspace_restriction".to_string(),
));
}
if let Some(workspace) = query.workspace {
let tags_o = CUSTOM_TAGS_PER_WORKSPACE.read().await;
let workspace_tags = tags_o
.1
.iter()
.filter(|(_, workspaces)| workspaces.contains(&workspace))
.map(|(tag, _)| tag.clone())
.collect::<Vec<String>>();
let all_tags = tags_o.0.clone();
return Ok(Json(
all_tags
.into_iter()
.chain(workspace_tags.into_iter())
.collect(),
));
} else if query.show_workspace_restriction.is_some_and(|x| x) {
let tags_o = CUSTOM_TAGS_PER_WORKSPACE.read().await;
let workspace_tags = tags_o
.1
.iter()
.map(|(tag, workspaces)| format!("{}({})", tag, workspaces.join("+")))
.collect::<Vec<String>>();
let all_tags = tags_o.0.clone();
return Ok(Json(
all_tags
.into_iter()
.chain(workspace_tags.into_iter())
.collect(),
));
}
Ok(Json(ALL_TAGS.read().await.clone().into()))
}
async fn get_default_tags_per_workspace() -> JsonResult<bool> {
@@ -354,7 +354,7 @@ pub(crate) async fn tarball_workspace(
ScriptLang::Rust => "rs",
ScriptLang::Ansible => "playbook.yml",
ScriptLang::CSharp => "cs",
ScriptLang::OracleDB => "oracle.sql",
ScriptLang::OracleDB => "odb.sql",
};
archive
.write_to_archive(&script.content, &format!("{}.{}", script.path, ext))
+2
View File
@@ -128,6 +128,7 @@ pub enum ScriptKind {
Failure,
Script,
Approval,
Preprocessor,
}
impl Display for ScriptKind {
@@ -137,6 +138,7 @@ impl Display for ScriptKind {
ScriptKind::Failure => "failure",
ScriptKind::Script => "script",
ScriptKind::Approval => "approval",
ScriptKind::Preprocessor => "preprocessor",
})?;
Ok(())
}
+1 -1
View File
@@ -87,7 +87,7 @@ lazy_static::lazy_static! {
pub static ref ALL_TAGS: Arc<RwLock<Vec<String>>> = Arc::new(RwLock::new(vec![]));
static ref CUSTOM_TAG_REGEX: Regex = Regex::new(r"^(\w+)\(((?:\w+)\+?)+\)$").unwrap();
static ref CUSTOM_TAG_REGEX: Regex = Regex::new(r"^([\w-]+)\(((?:[\w-])+\+?)+\)$").unwrap();
pub static ref DISABLE_BUNDLING: bool = std::env::var("DISABLE_BUNDLING")
.ok()
+6
View File
@@ -3550,6 +3550,12 @@ pub async fn push<'c, 'd>(
_low_level_priority
}; // else it remains empty, i.e. no priority
}
// prioritize flow steps to drain the queue faster
let final_priority = if flow_step_id.is_some() && final_priority.is_none() {
Some(0)
} else {
final_priority
};
let is_running = same_worker;
if let Some(flow) = raw_flow.as_ref() {
@@ -30,6 +30,7 @@ CMD="/usr/local/bin/uv pip install
$INDEX_URL_ARG $EXTRA_INDEX_URL_ARG $TRUSTED_HOST_ARG
--index-strategy unsafe-best-match
--system
--reinstall
"
echo $CMD
+16 -5
View File
@@ -235,11 +235,15 @@ fn gen_cs_proj(
let script_call = match (sig_meta.is_async, sig_meta.returns_void) {
(true, true) => format!(
r#"
{class_name}.Main({spread}).Wait();"#
{class_name}.Main({spread}).Wait();
File.WriteAllText("result.json", "null");
"#
),
(false, true) => format!(
r#"
{class_name}.Main({spread});"#
{class_name}.Main({spread});
File.WriteAllText("result.json", "null");
"#
),
(false, false) => format!(
@@ -282,9 +286,15 @@ namespace WindmillScriptCSharpInternal {{
using FileStream fs = File.OpenRead("args.json");
Args parsedArgs = JsonSerializer.Deserialize<Args>(fs);
File.WriteAllText("result.json", "null");
{script_call}
try
{{
{script_call}
}}
catch (Exception ex)
{{
Console.Error.WriteLine("Unhandeled Exception: " + ex.ToString());
Environment.Exit(1);
}}
}}
}}
}}
@@ -330,6 +340,7 @@ async fn build_cs_proj(
job_dir,
"--no-self-contained",
"-p:PublishSingleFile=true",
"-p:IncludeNativeLibrariesForSelfExtract=true",
])
.stdout(Stdio::piped())
.stderr(Stdio::piped());
+19 -22
View File
@@ -7,7 +7,6 @@ use std::{
};
use anyhow::anyhow;
use futures::lock::Mutex;
use itertools::Itertools;
use regex::Regex;
use serde_json::value::RawValue;
@@ -36,8 +35,6 @@ use windmill_common::variables::get_secret_value_as_admin;
use windmill_queue::{append_logs, CanceledBy};
lazy_static::lazy_static! {
static ref BUSY_WITH_UV_INSTALL: Mutex<()> = Mutex::new(());
static ref PYTHON_PATH: String =
std::env::var("PYTHON_PATH").unwrap_or_else(|_| "/usr/local/bin/python3".to_string());
@@ -649,7 +646,7 @@ def to_b_64(v: bytes):
b64 = base64.b64encode(v)
return b64.decode('ascii')
replace_nan = re.compile(r'(?:\bNaN\b|\\*\\u0000)')
replace_invalid_fields = re.compile(r'(?:\bNaN\b|\\*\\u0000|Infinity|\-Infinity)')
result_json = os.path.join(os.path.abspath(os.path.dirname(__file__)), "result.json")
@@ -666,7 +663,7 @@ def res_to_json(res):
for k, v in res.items():
if type(v).__name__ == 'bytes':
res[k] = to_b_64(v)
return re.sub(replace_nan, ' null ', json.dumps(res, separators=(',', ':'), default=str).replace('\n', ''))
return re.sub(replace_invalid_fields, ' null ', json.dumps(res, separators=(',', ':'), default=str).replace('\n', ''))
try:
{preprocessor}
@@ -1248,6 +1245,8 @@ async fn spawn_uv_install(
"--target",
venv_p,
"--no-cache",
// If we invoke uv pip install, then we want to overwrite existing data
"--reinstall",
]
};
@@ -1356,7 +1355,6 @@ pub async fn handle_python_reqs(
mut no_uv_install: bool,
is_ansible: bool,
) -> error::Result<Vec<String>> {
let lock = BUSY_WITH_UV_INSTALL.lock().await;
let counter_arc = Arc::new(tokio::sync::Mutex::new(0));
// Append logs with line like this:
// [9/21] + requests==2.32.3 << (S3) | in 57ms
@@ -1486,10 +1484,11 @@ pub async fn handle_python_reqs(
"{py_prefix}/{}",
req.replace(' ', "").replace('/', "").replace(':', "")
);
if metadata(&venv_p).await.is_ok() {
if metadata(venv_p.clone() + "/.valid.windmill").await.is_ok() {
req_paths.push(venv_p);
in_cache.push(req.to_string());
} else {
// There is no valid or no wheel at all. Regardless of if there is content or not, we will overwrite it with --reinstall flag
req_with_penv.push((req.to_string(), venv_p));
}
}
@@ -1520,12 +1519,6 @@ pub async fn handle_python_reqs(
let pids = Arc::new(tokio::sync::Mutex::new(vec![None; total_to_install]));
let mem_peak_thread_safe = Arc::new(tokio::sync::Mutex::new(0));
{
// when we cancel the job, it has up to 1 second window before actually getting cancelled
// Thus the directory with wheel in windmill's cache cleaned only after that.
// If we manage to start new job during that period windmill might see that wanted wheel is already there (because we have not cleaned it yet)
// and write it to installed wheels, meanwhile previous job will clean that wheel.
// To fix that we create lock, which will pipeline all uv installs on worker
let _lock = lock;
let pids = pids.clone();
let mem_peak_thread_safe = mem_peak_thread_safe.clone();
tokio::spawn(async move {
@@ -1866,6 +1859,17 @@ pub async fn handle_python_reqs(
);
pids.lock().await.get_mut(i).and_then(|e| e.take());
// Create a file to indicate that installation was successfull
let valid_path = venv_p.clone() + "/.valid.windmill";
// This is atomic operation, meaning, that it either completes and wheel is valid,
// or it does not and wheel is invalid and will be reinstalled next run
if let Err(e) = File::create(&valid_path).await{
tracing::error!(
workspace_id = %w_id,
job_id = %job_id,
"Failed to create {}!\n{e}\n
This file needed for python jobs to function", valid_path)
};
Ok(())
}));
}
@@ -1882,13 +1886,6 @@ pub async fn handle_python_reqs(
"Env installation failed: {:?}",
e
);
if let Err(e) = fs::remove_dir_all(&venv_p) {
tracing::warn!(
workspace_id = %w_id,
"Failed to remove cache dir: {:?}",
e
);
}
} else {
req_paths.push(venv_p);
}
@@ -2012,7 +2009,7 @@ def to_b_64(v: bytes):
b64 = base64.b64encode(v)
return b64.decode('ascii')
replace_nan = re.compile(r'(?:\bNaN\b|\\u0000)')
replace_invalid_fields = re.compile(r'(?:\bNaN\b|\\u0000|Infinity|\-Infinity)')
sys.stdout.write('start\n')
for line in sys.stdin:
@@ -2040,7 +2037,7 @@ for line in sys.stdin:
for k, v in res.items():
if type(v).__name__ == 'bytes':
res[k] = to_b_64(v)
res_json = re.sub(replace_nan, ' null ', json.dumps(res, separators=(',', ':'), default=str).replace('\n', ''))
res_json = re.sub(replace_invalid_fields, ' null ', json.dumps(res, separators=(',', ':'), default=str).replace('\n', ''))
sys.stdout.write("wm_res[success]:" + res_json + "\n")
except BaseException as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
+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.447.4";
export const VERSION = "v1.447.6";
export async function login(email: string, password: string): Promise<string> {
return await windmill.UserService.login({
+11 -1
View File
@@ -77,6 +77,7 @@ func main() (interface{}, error) {
bash: `echo "Hello world"
`,
oracledb: `SELECT 'Hello world' AS message`,
powershell: `Write-Output "Hello world"`,
php: `<?php
@@ -85,6 +86,15 @@ function main() {
}
`,
csharp: `class Script
{
public static void Main()
{
Console.WriteLine("Hello World");
}
}
`,
rust: `fn main() -> Result<(), String> {
println!("Hello World");
Ok(())
@@ -103,5 +113,5 @@ inventory:
- name: Print debug message
debug:
msg: "Hello, world!"
`
`,
};
+1 -1
View File
@@ -54,7 +54,7 @@ export const OpenAPI: OpenAPIConfig = {
PASSWORD: undefined,
TOKEN: getEnv("WM_TOKEN"),
USERNAME: undefined,
VERSION: '1.425.1',
VERSION: '1.447.5',
WITH_CREDENTIALS: true,
interceptors: {
request: new Interceptors(),
+519 -39
View File
File diff suppressed because one or more lines are too long
+453 -35
View File
@@ -30,8 +30,8 @@ export type Script = {
};
lock?: string;
lock_error_logs?: string;
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval';
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | 'preprocessor';
starred: boolean;
tag?: string;
has_draft?: boolean;
@@ -51,11 +51,12 @@ export type Script = {
no_main_func: boolean;
codebase?: string;
has_preprocessor: boolean;
on_behalf_of_email?: string;
};
export type language = 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
export type language = 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
export type kind = 'script' | 'failure' | 'trigger' | 'command' | 'approval';
export type kind = 'script' | 'failure' | 'trigger' | 'command' | 'approval' | 'preprocessor';
export type NewScript = {
path: string;
@@ -68,8 +69,8 @@ export type NewScript = {
};
is_template?: boolean;
lock?: string;
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
kind?: 'script' | 'failure' | 'trigger' | 'command' | 'approval';
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
kind?: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | 'preprocessor';
tag?: string;
draft_only?: boolean;
envs?: Array<(string)>;
@@ -88,6 +89,7 @@ export type NewScript = {
no_main_func?: boolean;
codebase?: string;
has_preprocessor?: boolean;
on_behalf_of_email?: string;
};
export type NewScriptWithDraft = NewScript & {
@@ -146,7 +148,7 @@ export type QueuedJob = {
canceled_by?: string;
canceled_reason?: string;
last_ping?: string;
job_kind: 'script' | 'preview' | 'dependencies' | 'flowdependencies' | 'appdependencies' | 'flow' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow';
job_kind: 'script' | 'preview' | 'dependencies' | 'flowdependencies' | 'appdependencies' | 'flow' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow' | 'flowscript' | 'flownode' | 'appscript';
schedule_path?: string;
/**
* The user (u/userfoo) or group (g/groupfoo) whom
@@ -157,7 +159,7 @@ export type QueuedJob = {
flow_status?: FlowStatus;
raw_flow?: FlowValue;
is_flow_step: boolean;
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
email: string;
visible_to_owner: boolean;
mem_peak?: number;
@@ -168,7 +170,7 @@ export type QueuedJob = {
suspend?: number;
};
export type job_kind = 'script' | 'preview' | 'dependencies' | 'flowdependencies' | 'appdependencies' | 'flow' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow';
export type job_kind = 'script' | 'preview' | 'dependencies' | 'flowdependencies' | 'appdependencies' | 'flow' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow' | 'flowscript' | 'flownode' | 'appscript';
export type CompletedJob = {
workspace_id?: string;
@@ -189,7 +191,7 @@ export type CompletedJob = {
canceled: boolean;
canceled_by?: string;
canceled_reason?: string;
job_kind: 'script' | 'preview' | 'dependencies' | 'flow' | 'flowdependencies' | 'appdependencies' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow';
job_kind: 'script' | 'preview' | 'dependencies' | 'flow' | 'flowdependencies' | 'appdependencies' | 'flowpreview' | 'script_hub' | 'identity' | 'deploymentcallback' | 'singlescriptflow' | 'flowscript' | 'flownode' | 'appscript';
schedule_path?: string;
/**
* The user (u/userfoo) or group (g/groupfoo) whom
@@ -200,7 +202,7 @@ export type CompletedJob = {
flow_status?: FlowStatus;
raw_flow?: FlowValue;
is_flow_step: boolean;
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
is_skipped: boolean;
email: string;
visible_to_owner: boolean;
@@ -230,6 +232,7 @@ export type User = {
email: string;
username: string;
is_admin: boolean;
name?: string;
is_super_admin: boolean;
created_at: string;
operator: boolean;
@@ -373,7 +376,7 @@ export type Preview = {
content?: string;
path?: string;
args: ScriptArgs;
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
language?: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
tag?: string;
kind?: 'code' | 'identity' | 'http';
dedicated_worker?: boolean;
@@ -488,6 +491,7 @@ export type Schedule = {
no_flow_overlap?: boolean;
tag?: string;
paused_until?: string;
cron_version?: string;
};
export type ScheduleWJobs = Schedule & {
@@ -521,6 +525,7 @@ export type NewSchedule = {
summary?: string;
tag?: string;
paused_until?: string;
cron_version?: string;
};
export type EditSchedule = {
@@ -542,6 +547,7 @@ export type EditSchedule = {
summary?: string;
tag?: string;
paused_until?: string;
cron_version?: string;
};
export type HttpTrigger = {
@@ -607,6 +613,8 @@ export type TriggersCount = {
webhook_count?: number;
email_count?: number;
websocket_count?: number;
kafka_count?: number;
nats_count?: number;
};
export type WebsocketTrigger = {
@@ -629,8 +637,8 @@ export type WebsocketTrigger = {
key: string;
value: unknown;
}>;
initial_messages: Array<WebsocketTriggerInitialMessage>;
url_runnable_args: ScriptArgs;
initial_messages?: Array<WebsocketTriggerInitialMessage>;
url_runnable_args?: ScriptArgs;
};
export type NewWebsocketTrigger = {
@@ -643,8 +651,8 @@ export type NewWebsocketTrigger = {
key: string;
value: unknown;
}>;
initial_messages: Array<WebsocketTriggerInitialMessage>;
url_runnable_args: ScriptArgs;
initial_messages?: Array<WebsocketTriggerInitialMessage>;
url_runnable_args?: ScriptArgs;
};
export type EditWebsocketTrigger = {
@@ -656,8 +664,8 @@ export type EditWebsocketTrigger = {
key: string;
value: unknown;
}>;
initial_messages: Array<WebsocketTriggerInitialMessage>;
url_runnable_args: ScriptArgs;
initial_messages?: Array<WebsocketTriggerInitialMessage>;
url_runnable_args?: ScriptArgs;
};
export type WebsocketTriggerInitialMessage = {
@@ -670,6 +678,90 @@ export type WebsocketTriggerInitialMessage = {
};
};
export type KafkaTrigger = {
path: string;
edited_by: string;
edited_at: string;
script_path: string;
kafka_resource_path: string;
group_id: string;
topics: Array<(string)>;
is_flow: boolean;
extra_perms: {
[key: string]: (boolean);
};
email: string;
workspace_id: string;
server_id?: string;
last_server_ping?: string;
error?: string;
enabled: boolean;
};
export type NewKafkaTrigger = {
path: string;
script_path: string;
is_flow: boolean;
kafka_resource_path: string;
group_id: string;
topics: Array<(string)>;
enabled?: boolean;
};
export type EditKafkaTrigger = {
kafka_resource_path: string;
group_id: string;
topics: Array<(string)>;
path: string;
script_path: string;
is_flow: boolean;
};
export type NatsTrigger = {
path: string;
edited_by: string;
edited_at: string;
script_path: string;
nats_resource_path: string;
use_jetstream: boolean;
stream_name?: string;
consumer_name?: string;
subjects: Array<(string)>;
is_flow: boolean;
extra_perms: {
[key: string]: (boolean);
};
email: string;
workspace_id: string;
server_id?: string;
last_server_ping?: string;
error?: string;
enabled: boolean;
};
export type NewNatsTrigger = {
path: string;
script_path: string;
is_flow: boolean;
nats_resource_path: string;
use_jetstream: boolean;
stream_name?: string;
consumer_name?: string;
subjects: Array<(string)>;
enabled?: boolean;
};
export type EditNatsTrigger = {
nats_resource_path: string;
use_jetstream: boolean;
stream_name?: string;
consumer_name?: string;
subjects: Array<(string)>;
path: string;
script_path: string;
is_flow: boolean;
};
export type Group = {
name: string;
summary?: string;
@@ -724,6 +816,7 @@ export type UserWorkspaceList = {
id: string;
name: string;
username: string;
color: string;
}>;
};
@@ -731,6 +824,7 @@ export type CreateWorkspace = {
id: string;
name: string;
username?: string;
color?: string;
};
export type Workspace = {
@@ -738,6 +832,7 @@ export type Workspace = {
name: string;
owner: string;
domain?: string;
color?: string;
};
export type WorkspaceInvite = {
@@ -751,6 +846,7 @@ export type GlobalUserInfo = {
email: string;
login_type: 'password' | 'github';
super_admin: boolean;
devops?: boolean;
verified: boolean;
name?: string;
company?: string;
@@ -781,6 +877,7 @@ export type FlowMetadata = {
dedicated_worker?: boolean;
timeout?: number;
visible_to_runner_only?: boolean;
on_behalf_of_email?: string;
};
export type OpenFlowWPath = OpenFlow & {
@@ -791,6 +888,7 @@ export type OpenFlowWPath = OpenFlow & {
dedicated_worker?: boolean;
timeout?: number;
visible_to_runner_only?: boolean;
on_behalf_of_email?: string;
};
export type FlowPreview = {
@@ -870,6 +968,7 @@ export type AppWithLastVersion = {
extra_perms: {
[key: string]: (boolean);
};
custom_path?: string;
};
export type AppWithLastVersionWDraft = AppWithLastVersion & {
@@ -1012,7 +1111,7 @@ export type MetricDataPoint = {
export type RawScriptForDependencies = {
raw_code: string;
path: string;
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible';
language: 'python3' | 'deno' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'bun' | 'php' | 'rust' | 'ansible' | 'csharp';
};
export type ConcurrencyGroup = {
@@ -1107,6 +1206,23 @@ export type CriticalAlert = {
workspace_id?: (string) | null;
};
export type CaptureTriggerKind = 'webhook' | 'http' | 'websocket' | 'kafka' | 'email' | 'nats';
export type Capture = {
trigger_kind: CaptureTriggerKind;
payload: unknown;
trigger_extra?: unknown;
id: number;
created_at: string;
};
export type CaptureConfig = {
trigger_config?: unknown;
trigger_kind: CaptureTriggerKind;
error?: string;
last_server_ping?: string;
};
export type OpenFlow = {
summary: string;
description?: string;
@@ -1204,7 +1320,7 @@ export type RawScript = {
[key: string]: InputTransform;
};
content: string;
language: 'deno' | 'bun' | 'python3' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'php';
language: 'deno' | 'bun' | 'python3' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'php';
path?: string;
lock?: string;
type: 'rawscript';
@@ -1215,7 +1331,7 @@ export type RawScript = {
is_trigger?: boolean;
};
export type language2 = 'deno' | 'bun' | 'python3' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'graphql' | 'nativets' | 'php';
export type language2 = 'deno' | 'bun' | 'python3' | 'go' | 'bash' | 'powershell' | 'postgresql' | 'mysql' | 'bigquery' | 'snowflake' | 'mssql' | 'oracledb' | 'graphql' | 'nativets' | 'php';
export type PathScript = {
input_transforms: {
@@ -1345,6 +1461,8 @@ export type ParameterJobId = string;
export type ParameterPath = string;
export type ParameterCustomPath = string;
export type ParameterPathId = number;
export type ParameterPathVersion = number;
@@ -1551,6 +1669,8 @@ export type ParameterGetStarted = boolean;
export type ParameterConcurrencyId = string;
export type ParameterRunnableKind = 'script' | 'flow';
export type BackendVersionResponse = (string);
export type BackendUptodateResponse = (string);
@@ -1705,6 +1825,7 @@ export type GlobalUserUpdateData = {
*/
requestBody: {
is_super_admin?: boolean;
is_devops?: boolean;
name?: string;
};
};
@@ -1865,7 +1986,17 @@ export type GetCriticalAlertsData = {
pageSize?: number;
};
export type GetCriticalAlertsResponse = (Array<CriticalAlert>);
export type GetCriticalAlertsResponse = ({
alerts?: Array<CriticalAlert>;
/**
* Total number of rows matching the query.
*/
total_rows?: number;
/**
* Total number of pages based on the page size.
*/
total_pages?: number;
});
export type AcknowledgeCriticalAlertData = {
/**
@@ -1932,6 +2063,10 @@ export type ListGlobalSettingsResponse = (Array<GlobalSetting>);
export type GetCurrentEmailResponse = (string);
export type RefreshUserTokenData = {
ifExpiringInLessThanS?: number;
};
export type RefreshUserTokenResponse = (string);
export type GetTutorialProgressResponse = ({
@@ -2088,6 +2223,15 @@ export type ChangeWorkspaceIdData = {
export type ChangeWorkspaceIdResponse = (string);
export type ChangeWorkspaceColorData = {
requestBody?: {
color?: string;
};
workspace: string;
};
export type ChangeWorkspaceColorResponse = (string);
export type WhoisData = {
username: string;
workspace: string;
@@ -2152,6 +2296,7 @@ export type GetSettingsResponse = ({
default_app?: string;
default_scripts?: WorkspaceDefaultScripts;
mute_critical_alerts?: boolean;
color?: string;
});
export type GetDeployToData = {
@@ -2177,6 +2322,7 @@ export type GetPremiumInfoResponse = ({
usage?: number;
seats?: number;
automatic_billing: boolean;
owner: string;
});
export type SetAutomaticBillingData = {
@@ -2192,6 +2338,27 @@ export type SetAutomaticBillingData = {
export type SetAutomaticBillingResponse = (string);
export type GetThresholdAlertData = {
workspace: string;
};
export type GetThresholdAlertResponse = ({
threshold_alert_amount?: number;
last_alert_sent?: string;
});
export type SetThresholdAlertData = {
/**
* threshold alert info
*/
requestBody: {
threshold_alert_amount?: number;
};
workspace: string;
};
export type SetThresholdAlertResponse = (string);
export type EditSlackCommandData = {
/**
* WorkspaceInvite
@@ -2417,6 +2584,8 @@ export type GetUsedTriggersData = {
export type GetUsedTriggersResponse = ({
http_routes_used: boolean;
websocket_used: boolean;
kafka_used: boolean;
nats_used: boolean;
});
export type ListUsersData = {
@@ -2589,7 +2758,17 @@ export type WorkspaceGetCriticalAlertsData = {
workspace: string;
};
export type WorkspaceGetCriticalAlertsResponse = (Array<CriticalAlert>);
export type WorkspaceGetCriticalAlertsResponse = ({
alerts?: Array<CriticalAlert>;
/**
* Total number of rows matching the query.
*/
total_rows?: number;
/**
* Total number of pages based on the page size.
*/
total_pages?: number;
});
export type WorkspaceAcknowledgeCriticalAlertData = {
/**
@@ -2983,6 +3162,14 @@ export type GetHubAppByIdResponse = ({
};
});
export type GetPublicAppByCustomPathData = {
customPath: string;
};
export type GetPublicAppByCustomPathResponse = ((AppWithLastVersion & {
workspace_id?: string;
}));
export type GetHubScriptContentByPathData = {
path: string;
};
@@ -3212,6 +3399,11 @@ export type ToggleWorkspaceErrorHandlerForScriptData = {
export type ToggleWorkspaceErrorHandlerForScriptResponse = (string);
export type GetCustomTagsData = {
showWorkspaceRestriction?: boolean;
workspace?: string;
};
export type GetCustomTagsResponse = (Array<(string)>);
export type GeDefaultTagsResponse = (Array<(string)>);
@@ -3887,6 +4079,7 @@ export type CreateAppData = {
policy: Policy;
draft_only?: boolean;
deployment_message?: string;
custom_path?: string;
};
workspace: string;
};
@@ -3908,6 +4101,13 @@ export type GetAppByPathData = {
export type GetAppByPathResponse = (AppWithLastVersion);
export type GetAppLiteByPathData = {
path: string;
workspace: string;
};
export type GetAppLiteByPathResponse = (AppWithLastVersion);
export type GetAppByPathWithDraftData = {
path: string;
workspace: string;
@@ -4025,12 +4225,20 @@ export type UpdateAppData = {
value?: unknown;
policy?: Policy;
deployment_message?: string;
custom_path?: string;
};
workspace: string;
};
export type UpdateAppResponse = (string);
export type CustomPathExistsData = {
customPath: string;
workspace: string;
};
export type CustomPathExistsResponse = (boolean);
export type ExecuteComponentData = {
path: string;
/**
@@ -4039,6 +4247,7 @@ export type ExecuteComponentData = {
requestBody: {
component: string;
path?: string;
version?: number;
args: unknown;
raw_code?: {
content: string;
@@ -4047,6 +4256,7 @@ export type ExecuteComponentData = {
lock?: string;
cache_ttl?: number;
};
id?: number;
force_viewer_static_fields?: {
[key: string]: unknown;
};
@@ -4892,6 +5102,20 @@ export type GetResumeUrlsResponse = ({
cancel: string;
});
export type GetSlackApprovalPayloadData = {
approver?: string;
channelId: string;
defaultArgsJson?: string;
dynamicEnumsJson?: string;
flowStepId: string;
id: string;
message?: string;
slackResourcePath: string;
workspace: string;
};
export type GetSlackApprovalPayloadResponse = (unknown);
export type ResumeSuspendedJobGetData = {
approver?: string;
id: string;
@@ -4997,6 +5221,7 @@ export type PreviewScheduleData = {
requestBody: {
schedule: string;
timezone: string;
cron_version?: string;
};
};
@@ -5265,6 +5490,156 @@ export type SetWebsocketTriggerEnabledData = {
export type SetWebsocketTriggerEnabledResponse = (string);
export type CreateKafkaTriggerData = {
/**
* new kafka trigger
*/
requestBody: NewKafkaTrigger;
workspace: string;
};
export type CreateKafkaTriggerResponse = (string);
export type UpdateKafkaTriggerData = {
path: string;
/**
* updated trigger
*/
requestBody: EditKafkaTrigger;
workspace: string;
};
export type UpdateKafkaTriggerResponse = (string);
export type DeleteKafkaTriggerData = {
path: string;
workspace: string;
};
export type DeleteKafkaTriggerResponse = (string);
export type GetKafkaTriggerData = {
path: string;
workspace: string;
};
export type GetKafkaTriggerResponse = (KafkaTrigger);
export type ListKafkaTriggersData = {
isFlow?: boolean;
/**
* which page to return (start at 1, default 1)
*/
page?: number;
/**
* filter by path
*/
path?: string;
pathStart?: string;
/**
* number of items to return for a given page (default 30, max 100)
*/
perPage?: number;
workspace: string;
};
export type ListKafkaTriggersResponse = (Array<KafkaTrigger>);
export type ExistsKafkaTriggerData = {
path: string;
workspace: string;
};
export type ExistsKafkaTriggerResponse = (boolean);
export type SetKafkaTriggerEnabledData = {
path: string;
/**
* updated kafka trigger enable
*/
requestBody: {
enabled: boolean;
};
workspace: string;
};
export type SetKafkaTriggerEnabledResponse = (string);
export type CreateNatsTriggerData = {
/**
* new nats trigger
*/
requestBody: NewNatsTrigger;
workspace: string;
};
export type CreateNatsTriggerResponse = (string);
export type UpdateNatsTriggerData = {
path: string;
/**
* updated trigger
*/
requestBody: EditNatsTrigger;
workspace: string;
};
export type UpdateNatsTriggerResponse = (string);
export type DeleteNatsTriggerData = {
path: string;
workspace: string;
};
export type DeleteNatsTriggerResponse = (string);
export type GetNatsTriggerData = {
path: string;
workspace: string;
};
export type GetNatsTriggerResponse = (NatsTrigger);
export type ListNatsTriggersData = {
isFlow?: boolean;
/**
* which page to return (start at 1, default 1)
*/
page?: number;
/**
* filter by path
*/
path?: string;
pathStart?: string;
/**
* number of items to return for a given page (default 30, max 100)
*/
perPage?: number;
workspace: string;
};
export type ListNatsTriggersResponse = (Array<NatsTrigger>);
export type ExistsNatsTriggerData = {
path: string;
workspace: string;
};
export type ExistsNatsTriggerResponse = (boolean);
export type SetNatsTriggerEnabledData = {
path: string;
/**
* updated nats trigger enable
*/
requestBody: {
enabled: boolean;
};
workspace: string;
};
export type SetNatsTriggerEnabledResponse = (string);
export type ListInstanceGroupsResponse = (Array<InstanceGroup>);
export type GetInstanceGroupData = {
@@ -5612,7 +5987,7 @@ export type ListAutoscalingEventsData = {
export type ListAutoscalingEventsResponse = (Array<AutoscalingEvent>);
export type GetGranularAclsData = {
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger';
path: string;
workspace: string;
};
@@ -5622,7 +5997,7 @@ export type GetGranularAclsResponse = ({
});
export type AddGranularAclsData = {
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger';
path: string;
/**
* acl to add
@@ -5637,7 +6012,7 @@ export type AddGranularAclsData = {
export type AddGranularAclsResponse = (string);
export type RemoveGranularAclsData = {
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger';
kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger';
path: string;
/**
* acl to add
@@ -5650,26 +6025,63 @@ export type RemoveGranularAclsData = {
export type RemoveGranularAclsResponse = (string);
export type UpdateCaptureData = {
path: string;
export type SetCaptureConfigData = {
/**
* capture config
*/
requestBody: {
trigger_kind: CaptureTriggerKind;
path: string;
is_flow: boolean;
trigger_config?: {
[key: string]: unknown;
};
};
workspace: string;
};
export type UpdateCaptureResponse = (void);
export type SetCaptureConfigResponse = (unknown);
export type CreateCaptureData = {
export type PingCaptureConfigData = {
path: string;
runnableKind: 'script' | 'flow';
triggerKind: CaptureTriggerKind;
workspace: string;
};
export type CreateCaptureResponse = (unknown);
export type PingCaptureConfigResponse = (unknown);
export type GetCaptureData = {
export type GetCaptureConfigsData = {
path: string;
runnableKind: 'script' | 'flow';
workspace: string;
};
export type GetCaptureResponse = (unknown);
export type GetCaptureConfigsResponse = (Array<CaptureConfig>);
export type ListCapturesData = {
/**
* which page to return (start at 1, default 1)
*/
page?: number;
path: string;
/**
* number of items to return for a given page (default 30, max 100)
*/
perPage?: number;
runnableKind: 'script' | 'flow';
triggerKind?: CaptureTriggerKind;
workspace: string;
};
export type ListCapturesResponse = (Array<Capture>);
export type DeleteCaptureData = {
id: number;
workspace: string;
};
export type DeleteCaptureResponse = (unknown);
export type StarData = {
requestBody?: {
@@ -5692,6 +6104,7 @@ export type UnstarData = {
export type UnstarResponse = (unknown);
export type GetInputHistoryData = {
includePreview?: boolean;
/**
* which page to return (start at 1, default 1)
*/
@@ -6223,7 +6636,6 @@ export type SearchLogsIndexResponse = ({
});
export type CountSearchLogsIndexData = {
hosts: string;
maxTs?: string;
minTs?: string;
searchQuery: string;
@@ -6240,4 +6652,10 @@ export type CountSearchLogsIndexResponse = ({
count_per_host?: {
[key: string]: unknown;
};
});
});
export type ClearIndexData = {
idxName: 'JobIndex' | 'ServiceLogIndex';
};
export type ClearIndexResponse = (string);
+1 -1
View File
@@ -60,7 +60,7 @@ export {
// }
// });
export const VERSION = "1.447.4";
export const VERSION = "1.447.6";
const command = new Command()
.name("wmill")
+10
View File
@@ -26,8 +26,10 @@ import {
parse_powershell,
parse_python,
parse_rust,
parse_csharp,
parse_snowflake,
parse_sql,
parse_oracledb,
} from "./wasm/windmill_parser_wasm.generated.js";
import { Workspace } from "./workspace.ts";
import { SchemaProperty } from "./bootstrap/common.ts";
@@ -468,6 +470,12 @@ export function inferSchema(
{ name: "database", typ: { resource: "bigquery" } },
...inferedSchema.args,
];
} else if (language === "oracledb") {
inferedSchema = JSON.parse(parse_oracledb(content));
inferedSchema.args = [
{ name: "database", typ: { resource: "oracledb" } },
...inferedSchema.args,
];
} else if (language === "snowflake") {
inferedSchema = JSON.parse(parse_snowflake(content));
inferedSchema.args = [
@@ -500,6 +508,8 @@ export function inferSchema(
inferedSchema = JSON.parse(parse_php(content));
} else if (language === "rust") {
inferedSchema = JSON.parse(parse_rust(content));
} else if (language === "csharp") {
inferedSchema = JSON.parse(parse_csharp(content));
} else if (language === "ansible") {
inferedSchema = JSON.parse(parse_ansible(content));
} else {
+6
View File
@@ -510,6 +510,8 @@ export function filePathExtensionFromContentType(
return ".my.sql";
} else if (language === "bigquery") {
return ".bq.sql";
} else if (language === "oracledb") {
return ".odb.sql";
} else if (language === "snowflake") {
return ".sf.sql";
} else if (language === "mssql") {
@@ -528,6 +530,8 @@ export function filePathExtensionFromContentType(
return ".rs";
} else if (language === "ansible") {
return ".playbook.yml";
} else if (language === "csharp") {
return ".cs";
} else {
throw new Error("Invalid language: " + language);
}
@@ -544,6 +548,7 @@ export const exts = [
".pg.sql",
".my.sql",
".bq.sql",
".odb.sql",
".sf.sql",
".ms.sql",
".sql",
@@ -551,6 +556,7 @@ export const exts = [
".ps1",
".php",
".rs",
".cs",
".playbook.yml",
];
+6
View File
@@ -9,11 +9,13 @@ export type ScriptLanguage =
| "postgresql"
| "mysql"
| "bigquery"
| "oracledb"
| "snowflake"
| "mssql"
| "graphql"
| "php"
| "rust"
| "csharp"
| "ansible";
export function inferContentTypeFromFilePath(
@@ -36,6 +38,8 @@ export function inferContentTypeFromFilePath(
return "mysql";
} else if (contentPath.endsWith(".bq.sql")) {
return "bigquery";
} else if (contentPath.endsWith(".odb.sql")) {
return "oracledb";
} else if (contentPath.endsWith(".sf.sql")) {
return "snowflake";
} else if (contentPath.endsWith(".ms.sql")) {
@@ -52,6 +56,8 @@ export function inferContentTypeFromFilePath(
return "php";
} else if (contentPath.endsWith(".rs")) {
return "rust";
} else if (contentPath.endsWith(".cs")) {
return "csharp";
} else if (contentPath.endsWith(".playbook.yml")) {
return "ansible";
} else {
+3
View File
@@ -320,6 +320,7 @@ export function newPathAssigner(defaultTs: "bun" | "deno"): PathAssigner {
else if (language == "postgresql") ext = "pg.sql";
else if (language == "mysql") ext = "my.sql";
else if (language == "bigquery") ext = "bq.sql";
else if (language == "oracledb") ext = "odb.sql";
else if (language == "snowflake") ext = "sf.sql";
else if (language == "mssql") ext = "ms.sql";
else if (language == "graphql") ext = "gql";
@@ -327,6 +328,7 @@ export function newPathAssigner(defaultTs: "bun" | "deno"): PathAssigner {
else if (language == "frontend") ext = "frontend.js";
else if (language == "php") ext = "php";
else if (language == "rust") ext = "rs";
else if (language == "csharp") ext = "cs";
else if (language == "ansible") ext = "playbook.yml";
else ext = "no_ext";
@@ -647,6 +649,7 @@ export async function elementsToMap(
"js",
"lock",
"rs",
"cs",
"yml",
].includes(path.split(".").pop() ?? "") &&
!isFileResource(path)
+1
View File
@@ -202,6 +202,7 @@ export function getTypeStrFromPath(
parsed.ext == ".js" ||
parsed.ext == ".php" ||
parsed.ext == ".rs" ||
parsed.ext == ".cs" ||
(parsed.ext == ".yml" && parsed.name.split(".").pop() == "playbook")
) {
return "script";
+13 -1
View File
@@ -13,6 +13,7 @@ export interface InstantiateResult {
parse_python: typeof parse_python;
parse_sql: typeof parse_sql;
parse_mysql: typeof parse_mysql;
parse_oracledb: typeof parse_oracledb;
parse_bigquery: typeof parse_bigquery;
parse_snowflake: typeof parse_snowflake;
parse_mssql: typeof parse_mssql;
@@ -20,7 +21,8 @@ export interface InstantiateResult {
parse_graphql: typeof parse_graphql;
parse_php: typeof parse_php;
parse_rust: typeof parse_rust;
parse_ansible: typeof parse_ansible
parse_ansible: typeof parse_ansible;
parse_csharp: typeof parse_csharp
};
}
@@ -96,6 +98,11 @@ export function parse_mysql(code: string): string;
* @param {string} code
* @returns {string}
*/
export function parse_oracledb(code: string): string;
/**
* @param {string} code
* @returns {string}
*/
export function parse_bigquery(code: string): string;
/**
* @param {string} code
@@ -132,3 +139,8 @@ export function parse_rust(code: string): string;
* @returns {string}
*/
export function parse_ansible(code: string): string;
/**
* @param {string} code
* @returns {string}
*/
export function parse_csharp(code: string): string;
+187 -131
View File
@@ -4,7 +4,7 @@
// deno-fmt-ignore-file
/// <reference types="./windmill_parser_wasm.generated.d.ts" />
// source-hash: 6da62ad21f79c5b8fe442f1de939e367943e2665
// source-hash: f0b1d0be016a3874b6824c3458a87cf04fc171fd
let wasm;
const heap = new Array(128).fill(undefined);
@@ -15,7 +15,38 @@ function getObject(idx) {
return heap[idx];
}
let WASM_VECTOR_LEN = 0;
let heap_next = heap.length;
function dropObject(idx) {
if (idx < 132) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
const cachedTextDecoder = typeof TextDecoder !== "undefined"
? new TextDecoder("utf-8", { ignoreBOM: true, fatal: true })
: {
decode: () => {
throw Error("TextDecoder not available");
},
};
if (typeof TextDecoder !== "undefined") cachedTextDecoder.decode();
let cachedUint8Memory0 = null;
@@ -26,6 +57,35 @@ function getUint8Memory0() {
return cachedUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
function isLikeNone(x) {
return x === undefined || x === null;
}
let cachedFloat64Memory0 = null;
function getFloat64Memory0() {
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
}
return cachedFloat64Memory0;
}
let cachedInt32Memory0 = null;
function getInt32Memory0() {
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = typeof TextEncoder !== "undefined"
? new TextEncoder("utf-8")
: {
@@ -76,66 +136,6 @@ function passStringToWasm0(arg, malloc, realloc) {
return ptr;
}
function isLikeNone(x) {
return x === undefined || x === null;
}
let cachedInt32Memory0 = null;
function getInt32Memory0() {
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
let heap_next = heap.length;
function dropObject(idx) {
if (idx < 132) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
let cachedFloat64Memory0 = null;
function getFloat64Memory0() {
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
}
return cachedFloat64Memory0;
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
const 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 getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
let cachedBigInt64Memory0 = null;
function getBigInt64Memory0() {
@@ -472,6 +472,33 @@ export function parse_mysql(code) {
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_oracledb(code) {
let deferred2_0;
let deferred2_1;
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(
code,
wasm.__wbindgen_malloc,
wasm.__wbindgen_realloc,
);
const len0 = WASM_VECTOR_LEN;
wasm.parse_oracledb(retptr, ptr0, len0);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
deferred2_0 = r0;
deferred2_1 = r1;
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
/**
* @param {string} code
* @returns {string}
@@ -688,6 +715,33 @@ export function parse_ansible(code) {
}
}
/**
* @param {string} code
* @returns {string}
*/
export function parse_csharp(code) {
let deferred2_0;
let deferred2_1;
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = passStringToWasm0(
code,
wasm.__wbindgen_malloc,
wasm.__wbindgen_realloc,
);
const len0 = WASM_VECTOR_LEN;
wasm.parse_csharp(retptr, ptr0, len0);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
deferred2_0 = r0;
deferred2_1 = r1;
return getStringFromWasm0(r0, r1);
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
}
}
function handleError(f, args) {
try {
return f.apply(this, args);
@@ -698,71 +752,6 @@ function handleError(f, args) {
const imports = {
__wbindgen_placeholder__: {
__wbindgen_string_get: function (arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof obj === "string" ? obj : undefined;
var ptr1 = isLikeNone(ret)
? 0
: passStringToWasm0(
ret,
wasm.__wbindgen_malloc,
wasm.__wbindgen_realloc,
);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
},
__wbindgen_object_drop_ref: function (arg0) {
takeObject(arg0);
},
__wbindgen_boolean_get: function (arg0) {
const v = getObject(arg0);
const ret = typeof v === "boolean" ? (v ? 1 : 0) : 2;
return ret;
},
__wbindgen_is_bigint: function (arg0) {
const ret = typeof (getObject(arg0)) === "bigint";
return ret;
},
__wbindgen_number_get: function (arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof obj === "number" ? obj : undefined;
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
},
__wbindgen_is_object: function (arg0) {
const val = getObject(arg0);
const ret = typeof val === "object" && val !== null;
return ret;
},
__wbindgen_in: function (arg0, arg1) {
const ret = getObject(arg0) in getObject(arg1);
return ret;
},
__wbindgen_bigint_from_i64: function (arg0) {
const ret = arg0;
return addHeapObject(ret);
},
__wbindgen_jsval_eq: function (arg0, arg1) {
const ret = getObject(arg0) === getObject(arg1);
return ret;
},
__wbindgen_bigint_from_u64: function (arg0) {
const ret = BigInt.asUintN(64, arg0);
return addHeapObject(ret);
},
__wbindgen_error_new: function (arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
},
__wbg_eval_8243d86342a64a9b: function (arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
},
__wbindgen_jsval_loose_eq: function (arg0, arg1) {
const ret = getObject(arg0) == getObject(arg1);
return ret;
},
__wbg_get_bd8e338fbd5f5cc8: function (arg0, arg1) {
const ret = getObject(arg0)[arg1 >>> 0];
return addHeapObject(ret);
@@ -771,14 +760,22 @@ const imports = {
const ret = getObject(arg0).length;
return ret;
},
__wbindgen_is_function: function (arg0) {
const ret = typeof (getObject(arg0)) === "function";
__wbindgen_is_object: function (arg0) {
const val = getObject(arg0);
const ret = typeof val === "object" && val !== null;
return ret;
},
__wbg_next_40fc327bfc8770e6: function (arg0) {
const ret = getObject(arg0).next;
return addHeapObject(ret);
},
__wbindgen_is_function: function (arg0) {
const ret = typeof (getObject(arg0)) === "function";
return ret;
},
__wbindgen_object_drop_ref: function (arg0) {
takeObject(arg0);
},
__wbg_next_196c84450b364254: function () {
return handleError(function (arg0) {
const ret = getObject(arg0).next();
@@ -841,6 +838,10 @@ const imports = {
const ret = Object.entries(getObject(arg0));
return addHeapObject(ret);
},
__wbindgen_memory: function () {
const ret = wasm.memory;
return addHeapObject(ret);
},
__wbg_buffer_12d079cc21e14bdb: function (arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
@@ -866,6 +867,39 @@ const imports = {
const ret = result;
return ret;
},
__wbindgen_error_new: function (arg0, arg1) {
const ret = new Error(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
},
__wbindgen_jsval_loose_eq: function (arg0, arg1) {
const ret = getObject(arg0) == getObject(arg1);
return ret;
},
__wbindgen_boolean_get: function (arg0) {
const v = getObject(arg0);
const ret = typeof v === "boolean" ? (v ? 1 : 0) : 2;
return ret;
},
__wbindgen_number_get: function (arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof obj === "number" ? obj : undefined;
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
},
__wbindgen_string_get: function (arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof obj === "string" ? obj : undefined;
var ptr1 = isLikeNone(ret)
? 0
: passStringToWasm0(
ret,
wasm.__wbindgen_malloc,
wasm.__wbindgen_realloc,
);
var len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
},
__wbindgen_bigint_get_as_i64: function (arg0, arg1) {
const v = getObject(arg1);
const ret = typeof v === "bigint" ? v : undefined;
@@ -886,8 +920,28 @@ const imports = {
__wbindgen_throw: function (arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
},
__wbindgen_memory: function () {
const ret = wasm.memory;
__wbindgen_is_bigint: function (arg0) {
const ret = typeof (getObject(arg0)) === "bigint";
return ret;
},
__wbindgen_in: function (arg0, arg1) {
const ret = getObject(arg0) in getObject(arg1);
return ret;
},
__wbindgen_bigint_from_i64: function (arg0) {
const ret = arg0;
return addHeapObject(ret);
},
__wbindgen_jsval_eq: function (arg0, arg1) {
const ret = getObject(arg0) === getObject(arg1);
return ret;
},
__wbindgen_bigint_from_u64: function (arg0) {
const ret = BigInt.asUintN(64, arg0);
return addHeapObject(ret);
},
__wbg_eval_73a4cb0af5990ab1: function (arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
},
},
@@ -1031,6 +1085,7 @@ function getWasmInstanceExports() {
parse_python,
parse_sql,
parse_mysql,
parse_oracledb,
parse_bigquery,
parse_snowflake,
parse_mssql,
@@ -1039,6 +1094,7 @@ function getWasmInstanceExports() {
parse_php,
parse_rust,
parse_ansible,
parse_csharp,
};
}
Binary file not shown.
+3 -3
View File
@@ -61,10 +61,10 @@ RUN --mount=type=secret,id=rh_username \
RUN subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
RUN yum update -y && \
yum install -y libxml2-devel xmlsec1-devel xmlsec1-openssl-devel clang llvm-devel cmake libtool-ltdl-devel
yum install -y perl-FindBin perl-IPC-Cmd libxml2-devel xmlsec1-devel xmlsec1-openssl-devel clang llvm-devel cmake libtool-ltdl-devel
RUN --mount=type=cache,target=/usr/local/cargo/registry \
CARGO_NET_GIT_FETCH_WITH_CLI=true RUST_BACKTRACE=1 cargo chef cook --release --features "$features" --recipe-path recipe.json
# RUN --mount=type=cache,target=/usr/local/cargo/registry \
# CARGO_NET_GIT_FETCH_WITH_CLI=true RUST_BACKTRACE=1 cargo chef cook --release --features "$features" --recipe-path recipe.json
COPY ./openflow.openapi.yaml /openflow.openapi.yaml
COPY ./backend ./
+111
View File
@@ -0,0 +1,111 @@
#! /usr/bin/env nu
# ------------------------------------ #
# Build and Test docker images locally #
# run: #
# docker/docker.nu --help #
# ------------------------------------ #
let branch = git branch --show-current;
# TODO: Use podman
let use_podman = false;
# Build and Test docker images
#
# For more info run:
# docker.nu up --help
# docker.nu build --help
#
# Should be invoked in repo root
def main [] {
./docker/docker.nu --help;
}
# Run and Build (if not yet) docker image
def "main up" [
custom_dockerfile?: path # Any dockerfile that depends on root Dockerfile
--features(-f): string = "deno_core" # Features that will be passed to base Dockerfile to compile windmill
--yes(-y) # Say yes for every confirmation (TODO)
] {
let ident = get_ident $custom_dockerfile -f $features;
if not (sudo docker images | into string | str contains $ident) {
print $"($ident) is not found, building..."
main build $custom_dockerfile -f $features
} else {
print $"($ident) was found"
}
print $"Running: ($ident)"
sudo WM_IMAGE=($ident) docker compose up --pull never
}
# Build docker image
def "main build" [
custom_dockerfile?: path # Any dockerfile that depends on root Dockerfile
--features(-f): string = "deno_core" # Features that will be passed to base Dockerfile to compile windmill
--mock(-m) # Ignore building base image
--yes(-y) # Say yes for every confirmation (TODO)
--podman(-p) # Use podman (TODO)
] {
if not $mock {
build_base -f $features
}
if $custom_dockerfile != null {
let ident = get_ident $custom_dockerfile -f $features;
let tmpfile = patch $custom_dockerfile -f $features;
print $"Building image by path ($custom_dockerfile) with ident: ($ident)"
sudo docker build -f $tmpfile -t $ident ./
}
}
def build_base [
--features(-f): string
] {
if not ($features | str contains "deno_core") {
print "Warning! deno_core feature not enabled"
print "Compilation may fail"
}
if ($features | str contains "enterprise") {
print "Building in EE mode"
print "Is windmill ee private repo mounted? [Y/n]";
let inp = input listen --types [key]
if ($inp.code != "y") {
# print "You can use --auto-substitute(-s) to automatically mount ee private repo (TODO)"
print "Aborted"
return;
}
}
let ident = get_ident -f $features;
print $"Building base image with ident: ($ident)"
sudo docker build -t ($ident) . --build-arg features=($features)
}
# TODO
def clone_ee_private [] {
let rev = open backend/ee-repo-ref.txt
git clone --depth 1 git@github.com:windmill-labs/windmill-ee-private.git .docker.nu/private-ee-repo-rev-($rev)
# git checkout ddcfdfc18a9833a5fc4e62ad62a265ef1e06a0aa)
}
def get_ident [
custom_dockerfile?: path # Any dockerfile that depends on root Dockerfile
--features(-f): string = "deno_core" # Features that will be passed to base Dockerfile to compile windmill
] {
let feat_postfix = $features | split row ',' | each { |e| $e | str trim --left --right } | sort | str join "-";
if $custom_dockerfile != null {
let df_postfix = $"($custom_dockerfile)" | split row "Dockerfile" | get 1 | str downcase;
return ($branch | append $df_postfix | append $feat_postfix | str join "__");
} else {
return ($branch | append $feat_postfix | str join "-");
}
}
def patch [
file: path
--features(-f): string
] {
let tmpfile = $"(mktemp -d)/Dockerfile";
open $file | str replace 'ghcr.io/windmill-labs/windmill-ee:dev' (get_ident -f $features) | save $tmpfile;
return $tmpfile;
}
Generated
+9 -9
View File
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1735471104,
"narHash": "sha256-0q9NGQySwDQc7RhAV2ukfnu7Gxa5/ybJ2ANT8DQrQrs=",
"lastModified": 1736883708,
"narHash": "sha256-uQ+NQ0/xYU0N1CnXsa2zghgNaOPxWpMJXSUJJ9W7140=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "88195a94f390381c6afcdaa933c2f6ff93959cb4",
"rev": "eb62e6aa39ea67e0b8018ba8ea077efe65807dc8",
"type": "github"
},
"original": {
@@ -35,11 +35,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1728538411,
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
"lastModified": 1736320768,
"narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
"rev": "4bc9c909d9ac828a039f288cf872d16d38185db8",
"type": "github"
},
"original": {
@@ -61,11 +61,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1735612067,
"narHash": "sha256-rsjojgfPUf9tWuMXuuo2KAIoUZ49XGZQJSjFGOO8Cq4=",
"lastModified": 1737080704,
"narHash": "sha256-n+J2h9GM9ZpFOQUmtZoCr1+DFF/iO5UlmLJeHIxbZGY=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d199142e84bfaae476ffb4e09a70879d7918784d",
"rev": "f9953fe89f8b65401fc4d4a288940bc2cb072949",
"type": "github"
},
"original": {
+7 -2
View File
@@ -137,8 +137,13 @@
version = (pkgs.lib.strings.trim (builtins.readFile ./version.txt));
src = ./backend;
nativeBuildInputs = buildInputs ++ [ self.packages.${system}.windmill-client pkgs.perl ];
nativeBuildInputs = buildInputs
++ [ self.packages.${system}.windmill-client pkgs.perl ]
++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
pkgs.darwin.apple_sdk.frameworks.SystemConfiguration
];
cargoLock = {
lockFile = ./backend/Cargo.lock;
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "windmill-components",
"version": "1.447.4",
"version": "1.447.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "windmill-components",
"version": "1.447.4",
"version": "1.447.6",
"license": "AGPL-3.0",
"dependencies": {
"@anthropic-ai/sdk": "^0.32.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.447.4",
"version": "1.447.6",
"scripts": {
"dev": "vite dev",
"build": "vite build",
+3 -11
View File
@@ -16,25 +16,17 @@ export const action = (node) => {
const setInitialHeight = () => {
let height = 0
const style = window.getComputedStyle(node)
const visible = style?.getPropertyValue('visibility') === 'hidden'
if (visible === false) {
return
}
if (node.value) {
height = node.scrollHeight
height = Math.max(node.scrollHeight ?? 0, 30) + 2
} else {
if (node.placeholder) {
node.value = node.placeholder
height = node.scrollHeight
height = Math.max(node.scrollHeight ?? 0, 30) + 2
node.value = ''
} else {
node.value = '|'
node.style.height = '0px'
height = node.scrollHeight + 20
height = Math.max(node.scrollHeight ?? 0, 30) + 2
node.value = ''
}
}
@@ -8,6 +8,7 @@
export let placement: 'bottom-end' | 'top-end' = 'bottom-end'
export let color: 'nord' | 'dark' = 'dark'
export let disabled = false
export let showWorkspaceRestriction = false
</script>
<Popup
@@ -27,5 +28,5 @@
>
</Button>
</svelte:fragment>
<AssignableTagsInner on:refresh />
<AssignableTagsInner {showWorkspaceRestriction} on:refresh />
</Popup>
@@ -9,12 +9,16 @@
import { base } from '$lib/base'
import { createEventDispatcher } from 'svelte'
export let showWorkspaceRestriction = false
let newTag: string = ''
let customTags: string[] | undefined = undefined
async function loadCustomTags() {
try {
customTags = (await WorkerService.getCustomTags()) ?? []
customTags =
(await WorkerService.getCustomTags({
showWorkspaceRestriction
})) ?? []
} catch (err) {
sendUserToast(`Could not load global cache: ${err}`, true)
}
@@ -18,6 +18,7 @@
export let snowflakeAccountIdentifier = ''
export let oauths: Record<string, any> = {}
export let requirePreexistingUserForOauth: boolean = false
const windmillBuiltins = [
'github',
@@ -46,8 +47,6 @@
let resourceName = ''
let tab: 'sso' | 'oauth' | 'scim' = 'sso'
let requirePreexistingUserForOauth: boolean = false
</script>
<div>
@@ -272,7 +272,11 @@
>
{/if}
{:else if category == 'Auth/OAuth'}
<AuthSettings bind:oauths bind:snowflakeAccountIdentifier>
<AuthSettings
bind:oauths
bind:snowflakeAccountIdentifier
bind:requirePreexistingUserForOauth
>
<svelte:fragment slot="scim">
<div class="flex-col flex gap-2 pb-4">
{#each scimSamlSetting as setting}
+5 -5
View File
@@ -7,6 +7,8 @@
export let value = typeof initialValue === 'string' ? parseInt(initialValue) : initialValue
export let disabled: boolean = false
export let defaultValue: number | undefined = undefined
export let format: (value: number) => string = (v) => `${v}`
export let hideInput: boolean = false
let step: number = 1
@@ -23,10 +25,6 @@
$: axisStep = calculateAxisStep(min, max)
const format = (v, i, p) => {
return `${v}`
}
function handleKeyDown(event: KeyboardEvent) {
if (disabled) return
@@ -85,7 +83,9 @@
{/if}
</div>
<input bind:value type="number" class="!w-16 h-8 !text-xs mb-6" {max} {min} {disabled} />
{#if !hideInput}
<input bind:value type="number" class="!w-16 h-8 !text-xs mb-6" {max} {min} {disabled} />
{/if}
</div>
<style>
@@ -4,7 +4,7 @@
import CloseButton from './common/CloseButton.svelte'
import Toggle from './Toggle.svelte'
import Tooltip from './Tooltip.svelte'
import { userStore, workerTags } from '$lib/stores'
import { userStore, workerTags, workspaceStore } from '$lib/stores'
import { Button } from './common'
import { WorkerService } from '$lib/gen'
import DateTimeInput from './DateTimeInput.svelte'
@@ -31,7 +31,7 @@
async function loadWorkerGroups() {
if (!$workerTags) {
$workerTags = await WorkerService.getCustomTags()
$workerTags = await WorkerService.getCustomTags({ workspace: $workspaceStore })
}
}
</script>
@@ -43,6 +43,7 @@
Rocket,
Save,
Settings,
Shuffle,
X
} from 'lucide-svelte'
import { sendUserToast } from '$lib/toast'
@@ -205,6 +206,13 @@
desc: 'Handle errors in flows after all retry attempts have been exhausted.',
documentationLink: 'https://www.windmill.dev/docs/flows/flow_error_handler',
Icon: Bug
},
{
value: 'preprocessor',
title: 'Preprocessor',
desc: 'Transform incoming requests before they are passed to the flow.',
documentationLink: 'https://www.windmill.dev/docs/core_concepts/preprocessors',
Icon: Shuffle
}
]
@@ -1290,6 +1298,7 @@
on:exitTriggers={() => {
captureTable?.loadCaptures(true)
}}
{args}
{initialPath}
schema={script.schema}
noEditor={true}
@@ -51,7 +51,7 @@
argName: 'database'
},
oracledb: {
code: `SELECT 1`,
code: `SELECT 1 FROM DUAL`,
lang: 'oracledb',
argName: 'database'
},
@@ -1,7 +1,7 @@
<script lang="ts">
import { Button } from '$lib/components/common'
import { ExternalLink, RotateCw, Loader2 } from 'lucide-svelte'
import { workerTags } from '$lib/stores'
import { workerTags, workspaceStore } from '$lib/stores'
import AssignableTags from './AssignableTags.svelte'
import { WorkerService } from '$lib/gen'
import WorkerTagSelect from './WorkerTagSelect.svelte'
@@ -13,7 +13,7 @@
loadWorkerGroups()
async function loadWorkerGroups() {
if (!$workerTags) {
$workerTags = await WorkerService.getCustomTags()
$workerTags = await WorkerService.getCustomTags({ workspace: $workspaceStore })
}
}
</script>
@@ -1,5 +1,5 @@
<script lang="ts">
import { workerTags } from '$lib/stores'
import { workerTags, workspaceStore } from '$lib/stores'
import { WorkerService } from '$lib/gen'
export let tag: string | undefined
@@ -11,7 +11,7 @@
async function loadWorkerGroups() {
if (!$workerTags) {
$workerTags = await WorkerService.getCustomTags()
$workerTags = await WorkerService.getCustomTags({ workspace: $workspaceStore })
}
}
</script>
@@ -56,6 +56,7 @@
const context = getContext<AppViewerContext>('AppViewerContext')
const contextPanel = getContext<ContextPanelContext>('ContextPanel')
const iterContext = getContext<ListContext>('ListWrapperContext')
const editorContext = getContext('AppEditorContext')
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
const { app, worldStore, selectedComponent, componentControl, darkMode, mode } = context
@@ -236,7 +237,8 @@
const componentContext = new Map<string, any>([
['AppViewerContext', context],
['ContextPanel', contextPanel]
['ContextPanel', contextPanel],
['AppEditorContext', editorContext]
])
const sortedActions: TableAction[] | undefined = computedOrder
@@ -96,8 +96,7 @@
on:applyArgs
on:addPreprocessor={async () => {
await insertNewPreprocessorModule(flowStore, flowStateStore, {
language: 'bun',
subkind: 'preprocessor'
language: 'bun'
})
$selectedId = 'preprocessor'
}}
@@ -113,6 +112,7 @@
}
}}
on:testWithArgs
args={$previewArgs}
currentPath={$pathStore}
{initialPath}
schema={$flowStore.schema}
@@ -1,7 +1,7 @@
<script lang="ts">
import { getContext } from 'svelte'
import type { FlowEditorContext } from '../types'
import { workerTags } from '$lib/stores'
import { workerTags, workspaceStore } from '$lib/stores'
import { WorkerService } from '$lib/gen'
import WorkerTagSelect from '$lib/components/WorkerTagSelect.svelte'
@@ -14,7 +14,7 @@
async function loadWorkerGroups() {
if (!$workerTags) {
$workerTags = await WorkerService.getCustomTags()
$workerTags = await WorkerService.getCustomTags({ workspace: $workspaceStore })
}
}
</script>
@@ -43,7 +43,7 @@
content: string
schema?: any
tag?: string
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | undefined
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | 'preprocessor' | undefined
envs?: string[]
ws_error_handler_muted?: boolean
dedicated_worker?: boolean
@@ -64,7 +64,7 @@
content: string
schema?: any
tag?: string
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | undefined
kind: 'script' | 'failure' | 'trigger' | 'command' | 'approval' | 'preprocessor' | undefined
envs?: string[]
ws_error_handler_muted?: boolean
dedicated_worker?: boolean
@@ -75,7 +75,7 @@ export async function pickFlow(
export async function createInlineScriptModule(
language: RawScript['language'],
kind: Script['kind'],
subkind: 'pgsql' | 'flow' | 'preprocessor',
subkind: 'pgsql' | 'flow' | undefined,
id: string,
summary?: string
): Promise<[FlowModule, FlowModuleState]> {
@@ -300,7 +300,6 @@ export async function insertNewPreprocessorModule(
flowStateStore: Writable<FlowState>,
inlineScript?: {
language: RawScript['language']
subkind: 'preprocessor'
},
wsScript?: { path: string; summary: string; hash: string | undefined }
) {
@@ -313,8 +312,8 @@ export async function insertNewPreprocessorModule(
if (inlineScript) {
;[module, state] = await createInlineScriptModule(
inlineScript.language,
'script',
inlineScript.subkind,
'preprocessor',
undefined,
'preprocessor'
)
} else if (wsScript) {
@@ -9,13 +9,16 @@
let timeout: NodeJS.Timeout | undefined = undefined
let visible = true
async function lookForTag(): Promise<void> {
try {
const existsWorkerWithTag = await WorkerService.existsWorkerWithTag({ tag })
noWorkerWithTag = !existsWorkerWithTag
if (noWorkerWithTag) {
timeout = setTimeout(() => {
lookForTag()
if (visible) {
lookForTag()
}
}, 1000)
}
} catch (err) {
@@ -26,6 +29,7 @@
lookForTag()
onDestroy(() => {
visible = false
if (timeout) {
clearTimeout(timeout)
}
@@ -1,15 +1,20 @@
<script lang="ts">
import { base } from '$lib/base'
import { capitalize, sendUserToast } from '$lib/utils'
import { capitalize, pluralize, sendUserToast } from '$lib/utils'
import DataTable from '$lib/components/table/DataTable.svelte'
import Cell from '$lib/components/table/Cell.svelte'
import { WorkspaceService, type User, UserService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { Button } from '../common'
import Tooltip from '../Tooltip.svelte'
import { ExternalLink, Loader2 } from 'lucide-svelte'
import { ExternalLink, Loader2, Pen, X } from 'lucide-svelte'
import { twMerge } from 'tailwind-merge'
import Toggle from '../Toggle.svelte'
import Section from '../Section.svelte'
import Range from '../Range.svelte'
import Label from '../Label.svelte'
import Modal from '../common/modal/Modal.svelte'
import { slide } from 'svelte/transition'
export let plan: string | undefined
export let customer_id: string | undefined
@@ -24,9 +29,10 @@
developerNb: number
operatorNb: number
seatsFromUsers: number
seatsFromComps: number
seatsFromExtraComps: number
usedSeats: number
automatic_billing: boolean
owner: string
}
| undefined = undefined
const plans = {
@@ -54,6 +60,7 @@
if ($workspaceStore) {
loadPremiumInfo()
listUsers()
getThresholdAlert()
}
}
@@ -66,16 +73,17 @@
const developerNb = users?.filter((x) => !x.operator)?.length ?? 0
const operatorNb = users?.filter((x) => x.operator)?.length ?? 0
const seatsFromUsers = Math.ceil(developerNb + operatorNb / 2)
const seatsFromComps = Math.ceil((info.usage ?? 0) / 10000)
const usedSeats = Math.max(seatsFromUsers, seatsFromComps)
const seatsFromExtraComps = Math.max(Math.ceil((info.usage ?? 0) / 10000) - seatsFromUsers, 0)
const usedSeats = seatsFromUsers + seatsFromExtraComps
premiumInfo = {
...info,
usage: info.usage ?? 0,
seats: info.seats ?? 1,
owner: info.owner,
developerNb,
operatorNb,
seatsFromUsers,
seatsFromComps,
seatsFromExtraComps,
usedSeats
}
}
@@ -84,7 +92,6 @@
async function setAutomaticBilling(ev) {
try {
billingModeLoading = true
console.log('toggle check', ev.detail)
await WorkspaceService.setAutomaticBilling({
workspace: $workspaceStore!,
requestBody: {
@@ -99,15 +106,86 @@
billingModeLoading = false
}
}
let thresholdAlert:
| {
threshold_alert_amount?: number
last_alert_sent?: string
}
| undefined = undefined
let newThresholdAlertAmount: number | undefined = undefined
let thresholdAlertOpen = false
async function getThresholdAlert() {
thresholdAlert = await WorkspaceService.getThresholdAlert({ workspace: $workspaceStore! })
}
async function setThresholdAlert() {
if (thresholdAlert) {
await WorkspaceService.setThresholdAlert({
workspace: $workspaceStore!,
requestBody: {
threshold_alert_amount: newThresholdAlertAmount
}
})
await getThresholdAlert()
sendUserToast('Threshold alert updated')
}
}
let estimatedDevs = 1
let estimatedOps = 0
$: estimatedSeats = estimatedDevs + Math.ceil(estimatedOps / 2)
let estimatedExecs = 1
function updateExecs() {
if (estimatedExecs < estimatedSeats) {
estimatedExecs = estimatedSeats
}
}
$: estimatedSeats && updateExecs()
</script>
<div class="flex flex-col gap-4 my-8">
<Modal bind:open={thresholdAlertOpen} title="Threshold alert">
<div class="flex flex-col gap-4">
<label class="block">
<span class="text-secondary text-sm">Threshold amount in $</span>
<input type="number" bind:value={newThresholdAlertAmount} />
</label>
</div>
<svelte:fragment slot="actions">
<Button
size="sm"
on:click={() => {
setThresholdAlert()
thresholdAlertOpen = false
}}
>
Save
</Button>
</svelte:fragment>
</Modal>
<div class="flex flex-col gap-4 mt-8">
<div class="flex flex-col gap-1">
<div class=" text-primary text-lg font-semibold">Plans</div>
<div class=" text-primary text-lg font-semibold">
{#if premiumInfo?.premium && plan}
Plan: {capitalize(plan)} plan{plan === 'team' && premiumInfo.automatic_billing
? ' (usage-based)'
: plan === 'team'
? ` (${premiumInfo.seats} seat${premiumInfo.seats > 1 ? 's' : ''})`
: ''}
{:else}
Plan: Free plan
{/if}
</div>
</div>
</div>
{#if customer_id}
<div class="mt-2 mb-2">
<div class="mt-2">
<Button
endIcon={{ icon: ExternalLink }}
color="dark"
@@ -119,19 +197,12 @@
</div>
{/if}
<div class="text-xs my-4">
<div class="text-xs">
{#if premiumInfo?.premium}
<div class="flex flex-col gap-0.5">
<div class="flex flex-col gap-8 my-8">
{#if plan}
<div class="text-base inline font-bold leading-8 mb-2">
Current plan: {capitalize(plan)} plan{plan === 'team' && premiumInfo.automatic_billing
? ' (usage-based)'
: plan === 'team'
? ` (${premiumInfo.seats} seat${premiumInfo.seats > 1 ? 's' : ''})`
: ''}
</div>
{#if plan === 'team'}
<div class="flex flex-row items-center gap-2 mb-4">
{#if plan === 'team' && !premiumInfo?.automatic_billing}
<div class="flex flex-row items-center gap-2">
<Toggle
checked={premiumInfo?.automatic_billing}
options={{
@@ -155,6 +226,54 @@
{/if}
{#if plan}
{#if premiumInfo?.automatic_billing}
<div class="flex flex-col gap-1.5">
<p class="font-semibold text-sm">Billing threshold email alert</p>
<div class="flex flex-row gap-0.5 items-center">
<p class="text-base text-secondary mr-0.5"
>{thresholdAlert?.threshold_alert_amount
? thresholdAlert?.threshold_alert_amount + '$'
: 'Not set'}</p
>
<Button
on:click={() => {
newThresholdAlertAmount = thresholdAlert?.threshold_alert_amount ?? 10
thresholdAlertOpen = true
}}
size="xs"
spacingSize="xs2"
variant="border"
color="light"
iconOnly
startIcon={{
icon: Pen
}}
/>
{#if thresholdAlert?.threshold_alert_amount}
<Button
on:click={() => {
if (thresholdAlert) {
newThresholdAlertAmount = undefined
setThresholdAlert()
}
}}
variant="border"
size="xs"
spacingSize="xs2"
color="light"
iconOnly
startIcon={{
icon: X
}}
/>
{/if}
</div>
<p class="italic text-xs"
>An email notification will be sent to {premiumInfo.owner} if the specified threshold amount
is reached during a given month.</p
>
</div>
{/if}
<div class="w-full">
<DataTable>
<tbody class="divide-y">
@@ -187,9 +306,7 @@
</Cell>
</tr>
<tr>
<Cell first
><div class="font-semibold">Minimum number of seats needed for users</div></Cell
>
<Cell first><div class="font-semibold">Number of seats for users</div></Cell>
<Cell last numeric>
<div class="text-base font-bold">
u = ceil({premiumInfo.developerNb} + {premiumInfo.operatorNb}/2) = {premiumInfo.seatsFromUsers}
@@ -204,14 +321,22 @@
</div>
</Cell>
</tr>
<tr>
<Cell first>Included computations with users (10k per user seat)</Cell>
<Cell last numeric>
<div class="text-base">
- {premiumInfo.seatsFromUsers * 10000}
</div>
</Cell>
</tr>
<tr>
<Cell first
><div class="font-semibold">Minimum number of seats needed for computations</div
></Cell
><div class="font-semibold">Number of seats for extra computations</div></Cell
>
<Cell last numeric>
<div class="text-base font-bold">
c = ceil({premiumInfo.usage} / 10 000) = {premiumInfo.seatsFromComps}
c = ceil({Math.max(0, premiumInfo.usage - premiumInfo.seatsFromUsers * 10000)} /
10 000) = {premiumInfo.seatsFromExtraComps}
</div>
</Cell>
</tr>
@@ -246,8 +371,7 @@
: ''
)}
>
max(u, c) = max({premiumInfo.seatsFromUsers}, {premiumInfo.seatsFromComps}) = {premiumInfo.usedSeats}{plan ===
'team' &&
u + c = {premiumInfo.usedSeats}{plan === 'team' &&
premiumInfo.usedSeats > premiumInfo.seats &&
!premiumInfo.automatic_billing
? ` > ${premiumInfo.seats}`
@@ -268,11 +392,82 @@
{/if}
</div>
{:else}
This workspace is <b>not</b> on a team plan. Users use their global free-tier quotas when doing executions
in this workspace. Upgrade to a Team or Enterprise plan to unlock unlimited executions in this workspace.
<div class="mb-8 mt-2">
This workspace is <b>not</b> on a team plan. Users use their global free-tier quotas when doing
executions in this workspace. Upgrade to a Team or Enterprise plan to unlock unlimited executions
in this workspace.
</div>
{/if}
</div>
<Section collapsable label="Cost estimator">
<div class="border p-4 rounded-md" transition:slide>
<Label label="Number of developers">
<Range min={1} max={20} bind:value={estimatedDevs} hideInput />
</Label>
<Label label="Number of operators">
<Range min={0} max={20} bind:value={estimatedOps} hideInput />
</Label>
<Label label="Number of executions">
<Range
min={estimatedSeats}
max={100}
bind:value={estimatedExecs}
format={(v) => `${v * 10}k`}
hideInput
/>
</Label>
<div class="mt-4 text-base">
<div class="flex flex-row justify-between">
<div>Seats for users = {estimatedDevs} devs + {estimatedOps} ops / 2</div>
<div>{pluralize(estimatedSeats, 'seat')}</div>
</div>
<div class="flex flex-row justify-between">
<div
>Extra computations = {estimatedExecs * 10}k execs - {estimatedSeats * 10}k included with
users</div
>
<div
>{(estimatedExecs - estimatedSeats) * 10}k extra execs = {pluralize(
estimatedExecs - estimatedSeats,
'seat'
)}</div
>
</div>
<div class="flex flex-row justify-between font-medium items-center">
<div>Total</div>
<div class="flex flex-col items-end">
<div>
{pluralize(estimatedSeats + (estimatedExecs - estimatedSeats), 'seat')} = {(estimatedSeats +
(estimatedExecs - estimatedSeats)) *
10}$ / month
</div>
{#if premiumInfo?.premium && plan === 'team'}
<button
class="text-xs text-blue-500 underline"
on:click={() => {
newThresholdAlertAmount = (estimatedSeats + (estimatedExecs - estimatedSeats)) * 10
thresholdAlertOpen = true
}}
>
Setup threshold email alert
</button>
{/if}
</div>
</div>
{#if (estimatedSeats + (estimatedExecs - estimatedSeats)) * 10 > 700}
<a
class="mt-4 text-teal-600 font-semibold text-center block underline"
href="https://www.windmill.dev/pricing"
target="_blank"
>
You should consider subscribing to Cloud Enterprise
</a>
{/if}
</div>
</div>
</Section>
<div class="text-base font-bold leading-8 mb-2 pt-8"> All plans </div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
@@ -189,7 +189,7 @@
{path}
hash={data?.hash}
token={data?.token}
{args}
runnableArgs={data?.args}
scopes={data?.scopes}
{showCapture}
{captureInfo}
@@ -208,6 +208,7 @@
{path}
{showCapture}
can_write={true}
runnableArgs={data?.args}
bind:args
headless
{captureInfo}
@@ -32,6 +32,7 @@
export let captureInfo: CaptureInfo | undefined = undefined
export let captureTable: CaptureTable | undefined = undefined
export let isValid = false
export let runnableArgs: any = {}
let validateTimeout: NodeJS.Timeout | undefined = undefined
let routeError: string = ''
@@ -107,9 +108,9 @@
<CopyableCodeBlock
disabled={!captureInfo.active}
code={`curl \\
-X POST ${captureURL} \\
-X ${http_method.toUpperCase()} ${captureURL} \\
-H 'Content-Type: application/json' \\
-d '{"foo": 42}'`}
-d '${JSON.stringify(runnableArgs ?? {}, null, 2)}'`}
language={bash}
/>
</Label>
@@ -17,6 +17,7 @@
export let isEditor: boolean = false
export let canHavePreprocessor: boolean = false
export let hasPreprocessor: boolean = false
export let args: Record<string, any> = {}
let routeEditor: RouteEditor
@@ -82,6 +83,7 @@
{canHavePreprocessor}
{hasPreprocessor}
{newItem}
data={{ args }}
/>
{#if !newItem}
<Section label="Routes">
@@ -27,7 +27,7 @@
export let isFlow: boolean
export let canHavePreprocessor: boolean = false
export let hasPreprocessor: boolean = false
export let args: Record<string, any> = {}
let eventStreamType: 'kafka' | 'nats' = 'kafka'
$: {
@@ -80,7 +80,7 @@
path={currentPath}
{hash}
{isFlow}
args={{}}
{args}
token=""
{newItem}
isEditor={true}
@@ -113,6 +113,7 @@
on:updateSchema
on:testWithArgs
{newItem}
{args}
path={currentPath}
{isFlow}
isEditor={true}
@@ -77,7 +77,6 @@
{disabled}
startIcon={{ icon: Save }}
on:click={() => {
console.log('saveTrigger', args)
dispatch('saveTrigger', {
config: args
})
@@ -36,7 +36,7 @@
{path}
hash={data?.hash}
token={data?.token}
{args}
runnableArgs={data?.args}
scopes={data?.scopes}
showCapture={false}
/>
@@ -29,7 +29,7 @@
export let path: string = ''
export let hash: string | undefined = undefined
export let token: string = ''
export let args: any
export let runnableArgs: any
export let triggerTokens: TriggerTokens | undefined = undefined
export let scopes: string[] = []
export let showCapture: boolean = false
@@ -117,7 +117,10 @@ async function triggerJob() {
${
requestType === 'get_path'
? '// Payload is a base64 encoded string of the arguments'
: `const body = JSON.stringify(${JSON.stringify(args, null, 2).replaceAll('\n', '\n\t')});`
: `const body = JSON.stringify(${JSON.stringify(runnableArgs ?? {}, null, 2).replaceAll(
'\n',
'\n\t'
)});`
}
const endpoint = \`${url}\`;
@@ -142,7 +145,10 @@ export async function main() {
// triggerJob function
let triggerJobFunction = `
async function triggerJob() {
const body = JSON.stringify(${JSON.stringify(args, null, 2).replaceAll('\n', '\n\t')});
const body = JSON.stringify(${JSON.stringify(runnableArgs ?? {}, null, 2).replaceAll(
'\n',
'\n\t'
)});
const endpoint = \`${url}\`;
return await fetch(endpoint, {
@@ -199,7 +205,7 @@ function waitForJobCompletion(UUID) {
function curlCode() {
return `TOKEN='${token}'
${requestType !== 'get_path' ? `BODY='${JSON.stringify(args)}'` : ''}
${requestType !== 'get_path' ? `BODY='${JSON.stringify(runnableArgs ?? {})}'` : ''}
URL='${url}'
${webhookType === 'sync' ? 'RESULT' : 'UUID'}=$(curl -s ${
requestType != 'get_path' ? "-H 'Content-Type: application/json'" : ''
@@ -230,12 +236,12 @@ done`
(tokenType === 'query'
? `?token=${token}${
requestType === 'get_path'
? `&payload=${encodeURIComponent(btoa(JSON.stringify(args)))}`
? `&payload=${encodeURIComponent(btoa(JSON.stringify(runnableArgs ?? {})))}`
: ''
}`
: `${
requestType === 'get_path'
? `?payload=${encodeURIComponent(btoa(JSON.stringify(args)))}`
? `?payload=${encodeURIComponent(btoa(JSON.stringify(runnableArgs ?? {})))}`
: ''
}`)
</script>
@@ -373,7 +379,7 @@ done`
{#if requestType !== 'get_path'}
<Label label="Body">
<ClipboardPanel content={JSON.stringify(args, null, 2)} />
<ClipboardPanel content={JSON.stringify(runnableArgs ?? {}, null, 2)} />
</Label>
{/if}
{#key requestType}
@@ -387,7 +393,7 @@ done`
</TabContent>
<TabContent value="curl" class="flex flex-col flex-1 h-full">
<div class="relative">
{#key args}
{#key runnableArgs}
{#key requestType}
{#key webhookType}
{#key tokenType}
@@ -408,7 +414,7 @@ done`
</div>
</TabContent>
<TabContent value="fetch">
{#key args}
{#key runnableArgs}
{#key requestType}
{#key webhookType}
{#key tokenType}
@@ -5,7 +5,7 @@
import TriggersEditorSection from './TriggersEditorSection.svelte'
export let token: string
export let args: any
export let args: Record<string, any> = {}
export let scopes: string[] = []
export let isFlow: boolean = false
export let hash: string | undefined = undefined
@@ -15,7 +15,7 @@
export let canHavePreprocessor: boolean = false
export let hasPreprocessor: boolean = false
let data: any = {
$: data = {
hash,
token,
scopes,
@@ -1,4 +1,4 @@
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory'
import { initEnhancedMonacoEnvironment } from 'monaco-languageclient/vscode/services'
// import cssWorker from 'monaco-editor-wrapper/workers/module/css?worker&url'
// import htmlWorker from 'monaco-editor-wrapper/workers/module/html?worker&url'
@@ -6,50 +6,56 @@ import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory'
// import editorWorker from 'monaco-editor-wrapper/workers/module/editor?worker&url'
export function buildWorkerDefinition() {
useWorkerFactory({
workerOverrides: {
ignoreMapping: true,
workerLoaders: {
editorWorkerService: () => {
return new Worker(
new URL('monaco-editor-wrapper/workers/module/editor', import.meta.url),
{
type: 'module'
}
)
},
javascript: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), {
type: 'module'
})
},
typescript: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), {
type: 'module'
})
},
json: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/json', import.meta.url), {
type: 'module'
})
},
html: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/html', import.meta.url), {
type: 'module'
})
},
css: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/css', import.meta.url), {
type: 'module'
})
},
graphql: () => {
console.log('Creating graphql worker')
return new Worker(new URL(`./graphql.worker.bundle.js`, import.meta.url), {
name: 'graphql'
})
}
const envEnhanced = initEnhancedMonacoEnvironment()
const getWorker = (moduleId: string, label: string) => {
console.log(`getWorker: moduleId: ${moduleId} label: ${label}`)
let selector = label
let workerLoaders = {
editorWorkerService: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/editor', import.meta.url), {
type: 'module'
})
},
javascript: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), {
type: 'module'
})
},
typescript: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), {
type: 'module'
})
},
json: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/json', import.meta.url), {
type: 'module'
})
},
html: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/html', import.meta.url), {
type: 'module'
})
},
css: () => {
return new Worker(new URL('monaco-editor-wrapper/workers/module/css', import.meta.url), {
type: 'module'
})
},
graphql: () => {
console.log('Creating graphql worker')
return new Worker(new URL(`./graphql.worker.bundle.js`, import.meta.url), {
name: 'graphql'
})
}
}
})
const workerFunc = workerLoaders[selector]
if (workerFunc !== undefined) {
return workerFunc()
} else {
throw new Error(`Unimplemented worker ${label} (${moduleId})`)
}
}
envEnhanced.getWorker = getWorker
}
+5 -6
View File
@@ -893,7 +893,6 @@ export function initialCode(
| 'docker'
| 'powershell'
| 'bunnative'
| 'preprocessor'
| undefined
): string {
if (!kind) {
@@ -911,8 +910,6 @@ export function initialCode(
return INITIAL_CODE.mysql.script
} else if (subkind === 'fetch') {
return INITIAL_CODE.deno.fetch
} else if (subkind === 'preprocessor') {
return INITIAL_CODE.deno.preprocessor
} else {
return INITIAL_CODE.deno.script
}
@@ -920,6 +917,8 @@ export function initialCode(
return INITIAL_CODE.deno.failure
} else if (kind === 'approval') {
return INITIAL_CODE.deno.approval
} else if (kind === 'preprocessor') {
return INITIAL_CODE.deno.preprocessor
} else {
return INITIAL_CODE.deno.script
}
@@ -930,10 +929,10 @@ export function initialCode(
return INITIAL_CODE.python3.approval
} else if (kind === 'failure') {
return INITIAL_CODE.python3.failure
} else if (kind === 'preprocessor') {
return INITIAL_CODE.python3.preprocessor
} else if (subkind === 'flow') {
return INITIAL_CODE.python3.clear
} else if (subkind === 'preprocessor') {
return INITIAL_CODE.python3.preprocessor
} else {
return INITIAL_CODE.python3.script
}
@@ -978,7 +977,7 @@ export function initialCode(
return INITIAL_CODE.bun.approval
} else if (kind === 'failure') {
return INITIAL_CODE.bun.failure
} else if (subkind === 'preprocessor') {
} else if (kind === 'preprocessor') {
return INITIAL_CODE.bun.preprocessor
} else if (subkind === 'flow') {
return INITIAL_CODE.bun.clear
@@ -282,6 +282,7 @@
<div class="flex flex-row-reverse w-full pb-2 items-center gap-4">
<div>
<AssignableTags
showWorkspaceRestriction
on:refresh={() => {
loadCustomTags()
}}
+12 -3
View File
@@ -2,7 +2,8 @@
// import EditableSchemaWrapper from '$lib/components/schema/EditableSchemaWrapper.svelte'
// import FlowBuilder from '$lib/components/FlowBuilder.svelte'
import ScriptBuilder from '$lib/components/ScriptBuilder.svelte'
// import ScriptBuilder from '$lib/components/ScriptBuilder.svelte'
import ScriptEditor from '$lib/components/ScriptEditor.svelte'
// import type { OpenFlow } from '$lib/gen'
// import { writable, type Writable } from 'svelte/store'
@@ -50,7 +51,7 @@
}}
/> -->
<ScriptBuilder
<!-- <ScriptBuilder
script={{
summary: 'foo',
path: 'u/admin/foo',
@@ -58,4 +59,12 @@
language: 'python3',
content: 'print("foo")'
}}
/>
/> -->
<!-- path: "/path/to/script",
code: "console.log('Hello, world!');",
lang: "bun",
tag: "", -->
<div class="h-screen">
<ScriptEditor path="/path/to/script" code="console.log('Hello, world!');" lang="bun" tag="" />
</div>
+4 -1
View File
@@ -13,7 +13,7 @@ const version = JSON.parse(json)
const config = {
server: {
https: false,
port: 3000,
port: 3006,
proxy: {
'^/api/.*': {
target: process.env.REMOTE ?? 'https://app.windmill.dev/',
@@ -57,6 +57,9 @@ const config = {
},
dedupe: ['vscode', 'monaco-editor']
},
worker: {
format: 'es'
},
assetsInclude: ['**/*.wasm']
}
+2 -2
View File
@@ -4,8 +4,8 @@ verify_ssl = true
name = "pypi"
[packages]
wmill = ">=1.447.4"
wmill_pg = ">=1.447.4"
wmill = ">=1.447.6"
wmill_pg = ">=1.447.6"
sendgrid = "*"
mysql-connector-python = "*"
pymongo = "*"
+2 -1
View File
@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.447.4
version: 1.447.6
title: OpenFlow Spec
contact:
name: Ruben Fiszel
@@ -250,6 +250,7 @@ components:
- bigquery
- snowflake
- mssql
- oracledb
- graphql
- nativets
- php
@@ -12,7 +12,7 @@
RootModule = 'WindmillClient.psm1'
# Version number of this module.
ModuleVersion = '1.447.4'
ModuleVersion = '1.447.6'
# Supported PSEditions
# CompatiblePSEditions = @()
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill"
version = "1.447.4"
version = "1.447.6"
description = "A client library for accessing Windmill server wrapping the Windmill client API"
license = "Apache-2.0"
homepage = "https://windmill.dev"
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill-pg"
version = "1.447.4"
version = "1.447.6"
description = "An extension client for the wmill client library focused on pg"
license = "Apache-2.0"
homepage = "https://windmill.dev"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@windmill/windmill",
"version": "1.447.4",
"version": "1.447.6",
"exports": "./src/index.ts",
"publish": {
"exclude": ["!src", "./s3Types.ts", "./client.ts"]
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "windmill-client",
"description": "Windmill SDK client for browsers and Node.js",
"version": "1.447.4",
"version": "1.447.6",
"author": "Ruben Fiszel",
"license": "Apache 2.0",
"devDependencies": {
+1 -1
View File
@@ -1 +1 @@
1.447.4
1.447.6