diff --git a/.claude/settings.json b/.claude/settings.json index 0596b17e91..1ef3704831 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -55,7 +55,10 @@ "Read(**/*.pem)", "Read(**/*.key)", "Read(**/credentials.json)", - "Read(**/*secret*)", + "Read(**/.secret*)", + "Read(**/.secrets*)", + "Read(**/*.secret)", + "Read(**/*.secrets)", "Edit(.env)", "Edit(.env.*)", "Edit(**/.env)", diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml index e89a58b629..b4916714f2 100644 --- a/.github/workflows/codex-pr-review.yml +++ b/.github/workflows/codex-pr-review.yml @@ -82,10 +82,11 @@ jobs: EVENT_TITLE: ${{ github.event.pull_request.title }} EVENT_BODY: ${{ github.event.pull_request.body }} EVENT_FORK: ${{ github.event.pull_request.head.repo.fork }} + EVENT_AUTHOR: ${{ github.event.pull_request.user.login }} run: | if [ -n "$INPUT_PR_NUMBER" ]; then PR_JSON=$(gh pr view "$INPUT_PR_NUMBER" --repo "${{ github.repository }}" \ - --json number,baseRefName,baseRefOid,headRefOid,title,body,isCrossRepository) + --json number,baseRefName,baseRefOid,headRefOid,title,body,isCrossRepository,author) PR_NUMBER=$(echo "$PR_JSON" | jq -r '.number') BASE_REF=$(echo "$PR_JSON" | jq -r '.baseRefName') BASE_SHA=$(echo "$PR_JSON" | jq -r '.baseRefOid') @@ -93,6 +94,7 @@ jobs: PR_TITLE=$(echo "$PR_JSON" | jq -r '.title') PR_BODY=$(echo "$PR_JSON" | jq -r '.body // ""') IS_FORK=$(echo "$PR_JSON" | jq -r '.isCrossRepository') + PR_AUTHOR=$(echo "$PR_JSON" | jq -r '.author.login // ""') else PR_NUMBER="$EVENT_PR_NUMBER" BASE_REF="$EVENT_BASE_REF" @@ -101,6 +103,7 @@ jobs: PR_TITLE="$EVENT_TITLE" PR_BODY="$EVENT_BODY" IS_FORK="$EVENT_FORK" + PR_AUTHOR="$EVENT_AUTHOR" fi if [ "$IS_FORK" = "true" ]; then echo "Skipping Codex review for fork PR." @@ -113,6 +116,7 @@ jobs: echo "base_ref=$BASE_REF" echo "base_sha=$BASE_SHA" echo "head_sha=$HEAD_SHA" + echo "pr_author=$PR_AUTHOR" echo 'title<> "$GITHUB_OUTPUT" + PR_NUMBER="$INPUT_PR_NUMBER" + PR_AUTHOR=$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.user.login') else - echo "pr_number=$EVENT_PR_NUMBER" >> "$GITHUB_OUTPUT" + PR_NUMBER="$EVENT_PR_NUMBER" + PR_AUTHOR="$EVENT_PR_AUTHOR" fi + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "pr_author=$PR_AUTHOR" >> "$GITHUB_OUTPUT" - name: Fetch prior PR discussion id: prior @@ -148,6 +155,7 @@ jobs: prompt: | REPO: ${{ github.repository }} PR NUMBER: ${{ steps.resolve.outputs.pr_number }} + PR AUTHOR: ${{ steps.resolve.outputs.pr_author }} ${{ env.REVIEW_PROMPT }} claude_args: | diff --git a/REVIEW.md b/REVIEW.md index de311cccc6..21f5e50f26 100644 --- a/REVIEW.md +++ b/REVIEW.md @@ -9,7 +9,7 @@ You are reviewing a GitHub pull request for this repository. Apply this policy a ## Verdict (first line of the review) -Start every review with a single verdict line, before any other section. Pick exactly one: +Start every review with a single verdict line, before any other section (the only thing that may appear above the verdict is the optional `cc @` ping described in "Pinging the author" below). Pick exactly one: - **Good to merge** — no blocking issues and no nits worth surfacing. - **Mergeable, but should ideally address nits: ** — no blockers, but P2 findings that are worth a look. The list must name each nit briefly (e.g. "doc/code mismatch in `foo.rs`, half-finished `pub fn bar`"). @@ -17,6 +17,10 @@ Start every review with a single verdict line, before any other section. Pick ex The names in the list must match findings detailed later in the review. If you list a nit or issue here, it must appear with full context in the body. Do not invent items that aren't in the body, and do not bury blockers in the body without surfacing them in the verdict. +## Pinging the author + +If the prompt context provides a `PR AUTHOR` (GitHub login) and the verdict is NOT "Good to merge" (i.e. it is "Mergeable, but should ideally address nits: ..." or "Should address issues before merging: ..."), prepend a single line `cc @` to the top-level review comment, above the verdict line. This pings the author so they get a notification that there are items to address. Skip the ping entirely when the verdict is "Good to merge" — there is nothing for the author to act on. Do not add the ping to inline comments; the top-level summary comment is the only place it belongs. + ## Review policy - Only report issues you are confident are real and introduced by this pull request. diff --git a/backend/.sqlx/query-0c6e8f03a4e9f543cb85582e0aec1ed508d83695ef6d62ca06cfb612fd332b87.json b/backend/.sqlx/query-0c6e8f03a4e9f543cb85582e0aec1ed508d83695ef6d62ca06cfb612fd332b87.json deleted file mode 100644 index 7de0416a12..0000000000 --- a/backend/.sqlx/query-0c6e8f03a4e9f543cb85582e0aec1ed508d83695ef6d62ca06cfb612fd332b87.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT item_kind, path FROM ws_specific WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "item_kind", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "0c6e8f03a4e9f543cb85582e0aec1ed508d83695ef6d62ca06cfb612fd332b87" -} diff --git a/backend/.sqlx/query-8b92a7d04fcdd8e61178d7dab97c31e10f89481908c479b4039af5e94fa0f8ac.json b/backend/.sqlx/query-290599fc173947acb518344d6fb631af9f524389309f17ef04f70c773b1d5e75.json similarity index 85% rename from backend/.sqlx/query-8b92a7d04fcdd8e61178d7dab97c31e10f89481908c479b4039af5e94fa0f8ac.json rename to backend/.sqlx/query-290599fc173947acb518344d6fb631af9f524389309f17ef04f70c773b1d5e75.json index 415544ece9..ad296e9eda 100644 --- a/backend/.sqlx/query-8b92a7d04fcdd8e61178d7dab97c31e10f89481908c479b4039af5e94fa0f8ac.json +++ b/backend/.sqlx/query-290599fc173947acb518344d6fb631af9f524389309f17ef04f70c773b1d5e75.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT s.item_kind, s.path\n FROM ws_specific s\n WHERE s.workspace_id = $1\n AND (\n (s.item_kind = 'resource' AND EXISTS (\n SELECT 1 FROM resource r\n WHERE r.workspace_id = s.workspace_id AND r.path = s.path\n ))\n OR (s.item_kind = 'variable' AND EXISTS (\n SELECT 1 FROM variable v\n WHERE v.workspace_id = s.workspace_id AND v.path = s.path\n ))\n )\n ", + "query": "\n SELECT s.item_kind, s.path\n FROM ws_specific s\n WHERE s.workspace_id = $1\n AND (\n (s.item_kind = 'resource' AND EXISTS (\n SELECT 1 FROM resource r\n WHERE r.workspace_id = s.workspace_id AND r.path = s.path\n ))\n OR (s.item_kind = 'variable' AND EXISTS (\n SELECT 1 FROM variable v\n WHERE v.workspace_id = s.workspace_id AND v.path = s.path\n ))\n )\n ORDER BY s.item_kind, s.path\n ", "describe": { "columns": [ { @@ -24,5 +24,5 @@ false ] }, - "hash": "8b92a7d04fcdd8e61178d7dab97c31e10f89481908c479b4039af5e94fa0f8ac" + "hash": "290599fc173947acb518344d6fb631af9f524389309f17ef04f70c773b1d5e75" } diff --git a/backend/.sqlx/query-406bcbf55758b10243c8eaff1c349b8082c0052d626bf67e08317e56ab9ad026.json b/backend/.sqlx/query-406bcbf55758b10243c8eaff1c349b8082c0052d626bf67e08317e56ab9ad026.json deleted file mode 100644 index 2b5b68dfae..0000000000 --- a/backend/.sqlx/query-406bcbf55758b10243c8eaff1c349b8082c0052d626bf67e08317e56ab9ad026.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT label, email, scopes, workspace_id, super_admin, owner, expiration FROM token WHERE token_hash = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "label", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "scopes", - "type_info": "TextArray" - }, - { - "ordinal": 3, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "super_admin", - "type_info": "Bool" - }, - { - "ordinal": 5, - "name": "owner", - "type_info": "Varchar" - }, - { - "ordinal": 6, - "name": "expiration", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - true, - true, - true, - true, - false, - true, - true - ] - }, - "hash": "406bcbf55758b10243c8eaff1c349b8082c0052d626bf67e08317e56ab9ad026" -} diff --git a/backend/.sqlx/query-6be4bf59c404d2f557d1106c48c320bb3eff65255a44bd66799ae14288312ba4.json b/backend/.sqlx/query-6be4bf59c404d2f557d1106c48c320bb3eff65255a44bd66799ae14288312ba4.json deleted file mode 100644 index 0a39db6822..0000000000 --- a/backend/.sqlx/query-6be4bf59c404d2f557d1106c48c320bb3eff65255a44bd66799ae14288312ba4.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT EXISTS(SELECT 1 FROM variable WHERE workspace_id = $1 AND path = $2)", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "6be4bf59c404d2f557d1106c48c320bb3eff65255a44bd66799ae14288312ba4" -} diff --git a/backend/.sqlx/query-9c85ba8d41bedbcb5466f44a7d4cf6b4946e1fd337f00d243f518283783833c9.json b/backend/.sqlx/query-9c85ba8d41bedbcb5466f44a7d4cf6b4946e1fd337f00d243f518283783833c9.json new file mode 100644 index 0000000000..fce125c6d5 --- /dev/null +++ b/backend/.sqlx/query-9c85ba8d41bedbcb5466f44a7d4cf6b4946e1fd337f00d243f518283783833c9.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT bool_and(operator) FROM (\n SELECT operator FROM usr WHERE email = $1\n UNION ALL\n SELECT operator FROM workspace_invite WHERE email = $1\n ) t", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "bool_and", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "9c85ba8d41bedbcb5466f44a7d4cf6b4946e1fd337f00d243f518283783833c9" +} diff --git a/backend/.sqlx/query-b4162468afae99cf31c4668ca6769657fd73742b6ee8289b1e9736e381314cfb.json b/backend/.sqlx/query-b4162468afae99cf31c4668ca6769657fd73742b6ee8289b1e9736e381314cfb.json deleted file mode 100644 index 327032afb5..0000000000 --- a/backend/.sqlx/query-b4162468afae99cf31c4668ca6769657fd73742b6ee8289b1e9736e381314cfb.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT EXISTS(SELECT 1 FROM ws_specific WHERE workspace_id = $1 AND item_kind = 'variable' AND path = $2)", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "b4162468afae99cf31c4668ca6769657fd73742b6ee8289b1e9736e381314cfb" -} diff --git a/backend/.sqlx/query-e1ada31c1625b453c2ff85edbcd7ad51a4cd5cbdc2fa34038530070d6a579455.json b/backend/.sqlx/query-e1ada31c1625b453c2ff85edbcd7ad51a4cd5cbdc2fa34038530070d6a579455.json new file mode 100644 index 0000000000..f38c023cb3 --- /dev/null +++ b/backend/.sqlx/query-e1ada31c1625b453c2ff85edbcd7ad51a4cd5cbdc2fa34038530070d6a579455.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "WITH potential AS (\n SELECT email, operator FROM usr\n UNION\n SELECT email, operator FROM workspace_invite\n ),\n per_user AS (\n SELECT email, bool_and(operator) AS only_operator FROM potential GROUP BY email\n )\n SELECT\n COUNT(*) FILTER (WHERE NOT only_operator) AS \"authors!\",\n COUNT(*) FILTER (WHERE only_operator) AS \"operators!\"\n FROM per_user", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "authors!", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "operators!", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null, + null + ] + }, + "hash": "e1ada31c1625b453c2ff85edbcd7ad51a4cd5cbdc2fa34038530070d6a579455" +} diff --git a/backend/.sqlx/query-f8f756bc498e5f084851f98e1e8d8c74cdc672a903d566baf5ac5ef50a4da1bd.json b/backend/.sqlx/query-f8f756bc498e5f084851f98e1e8d8c74cdc672a903d566baf5ac5ef50a4da1bd.json new file mode 100644 index 0000000000..e4125ddab9 --- /dev/null +++ b/backend/.sqlx/query-f8f756bc498e5f084851f98e1e8d8c74cdc672a903d566baf5ac5ef50a4da1bd.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT memory, worker, native_mode FROM worker_ping WHERE ping_at > now() - interval '2 minutes'", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "memory", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "worker", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "native_mode", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + true, + false, + false + ] + }, + "hash": "f8f756bc498e5f084851f98e1e8d8c74cdc672a903d566baf5ac5ef50a4da1bd" +} diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 6952682391..82235725ee 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "addr2line" version = "0.25.1" @@ -21,12 +11,6 @@ dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.1" @@ -39,24 +23,10 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common 0.1.7", + "crypto-common", "generic-array", ] -[[package]] -name = "aead-gcm-stream" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70c8dec860340effb00f6945c49c0daaa6dac963602750db862eabb74bf7886" -dependencies = [ - "aead", - "aes 0.8.3", - "cipher 0.4.4", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "aes" version = "0.7.5" @@ -94,15 +64,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "aes-kw" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fa2b352dcefb5f7f3a5fb840e02665d311d878955380515e4fd50095dd3d8c" -dependencies = [ - "aes 0.8.3", -] - [[package]] name = "ahash" version = "0.7.8" @@ -203,7 +164,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -214,7 +175,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -279,9 +240,6 @@ name = "arrayvec" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -dependencies = [ - "serde", -] [[package]] name = "arrow" @@ -494,29 +452,10 @@ dependencies = [ ] [[package]] -name = "ash" -version = "0.37.3+1.3.251" +name = "ascii" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" -dependencies = [ - "libloading 0.7.4", -] - -[[package]] -name = "asn1-rs" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" -dependencies = [ - "asn1-rs-derive 0.4.0", - "asn1-rs-impl 0.1.0", - "displaydoc", - "nom 7.1.3", - "num-traits", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] name = "asn1-rs" @@ -524,28 +463,16 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ - "asn1-rs-derive 0.5.1", - "asn1-rs-impl 0.2.0", + "asn1-rs-derive", + "asn1-rs-impl", "displaydoc", - "nom 7.1.3", + "nom", "num-traits", "rusticata-macros", "thiserror 1.0.69", "time", ] -[[package]] -name = "asn1-rs-derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure 0.12.6", -] - [[package]] name = "asn1-rs-derive" version = "0.5.1" @@ -555,18 +482,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "synstructure 0.13.2", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "synstructure", ] [[package]] @@ -582,11 +498,10 @@ dependencies = [ [[package]] name = "ast_node" -version = "0.9.9" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9184f2b369b3e8625712493c89b785881f27eedc6cde480a81883cef78868b2" +checksum = "0a184645bcc6f52d69d8e7639720699c6a99efb711f886e251ed1d16db8dd90e" dependencies = [ - "proc-macro2", "quote", "swc_macros_common", "syn 2.0.117", @@ -1137,7 +1052,7 @@ dependencies = [ "bytes", "form_urlencoded", "hex", - "hmac 0.12.1", + "hmac", "http 0.2.12", "http 1.4.0", "percent-encoding", @@ -1326,7 +1241,7 @@ version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "576b0d6991c9c32bc14fc340582ef148311f924d41815f641a308b5d11e8e7cd" dependencies = [ - "base64-simd 0.8.0", + "base64-simd", "bytes", "bytes-utils", "futures-core", @@ -1518,7 +1433,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.9", + "miniz_oxide", "object", "rustc-demangle", "windows-link 0.2.1", @@ -1554,22 +1469,13 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64-simd" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" -dependencies = [ - "simd-abstraction", -] - [[package]] name = "base64-simd" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" dependencies = [ - "outref 0.5.2", + "outref", "vsimd", ] @@ -1581,9 +1487,9 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "better_scoped_tls" -version = "0.1.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297b153aa5e573b5863108a6ddc9d5c968bd0b20e75cc614ee9821d2f45679c7" +checksum = "7cd228125315b132eed175bf47619ac79b945b26e56b848ba203ae4ea8603609" dependencies = [ "scoped-tls", ] @@ -1610,26 +1516,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.117", -] - [[package]] name = "bindgen" version = "0.71.1" @@ -1670,15 +1556,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec 0.6.3", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -1759,19 +1636,13 @@ dependencies = [ "cpufeatures 0.3.0", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", + "block-padding", "generic-array", ] @@ -1784,22 +1655,13 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-buffer" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" -dependencies = [ - "hybrid-array", -] - [[package]] name = "block-modes" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" dependencies = [ - "block-padding 0.2.1", + "block-padding", "cipher 0.3.0", ] @@ -1809,15 +1671,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - [[package]] name = "bollard" version = "0.18.1" @@ -1895,7 +1748,7 @@ checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ "borsh-derive", "bytes", - "cfg_aliases 0.2.1", + "cfg_aliases", ] [[package]] @@ -1921,17 +1774,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "brotli" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor 4.0.3", -] - [[package]] name = "brotli" version = "7.0.0" @@ -2072,6 +1914,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bytes-str" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c60b5ce37e0b883c37eb89f79a1e26fbe9c1081945d024eee93e8d91a7e18b3" +dependencies = [ + "bytes", + "serde", +] + [[package]] name = "bytes-utils" version = "0.1.4" @@ -2107,12 +1959,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "cache_control" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" - [[package]] name = "candle-core" version = "0.9.2" @@ -2124,7 +1970,7 @@ dependencies = [ "gemm", "half", "libm", - "memmap2 0.9.10", + "memmap2", "num-traits", "num_cpus", "rand 0.9.0", @@ -2132,7 +1978,7 @@ dependencies = [ "rayon", "safetensors", "thiserror 2.0.18", - "yoke 0.8.2", + "yoke", "zip", ] @@ -2171,15 +2017,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "capacity_builder" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ec49028cb308564429cd8fac4ef21290067a0afe8f5955330a8d487d0d790c" -dependencies = [ - "itoa", -] - [[package]] name = "capacity_builder" version = "0.5.0" @@ -2187,8 +2024,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f2d24a6dcf0cd402a21b65d35340f3a49ff3475dc5fdac91d22d2733e6641c6" dependencies = [ "capacity_builder_macros", - "ecow", - "hipstr", "itoa", ] @@ -2203,12 +2038,12 @@ dependencies = [ ] [[package]] -name = "cbc" -version = "0.1.2" +name = "castaway" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ - "cipher 0.4.4", + "rustversion", ] [[package]] @@ -2241,7 +2076,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 7.1.3", + "nom", ] [[package]] @@ -2250,29 +2085,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chacha20" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "rand_core 0.10.1", -] - [[package]] name = "chrono" version = "0.4.44" @@ -2322,7 +2140,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common 0.1.7", + "crypto-common", "inout", ] @@ -2334,7 +2152,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading 0.8.9", + "libloading", ] [[package]] @@ -2377,15 +2195,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" -[[package]] -name = "clipboard-win" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" -dependencies = [ - "error-code", -] - [[package]] name = "cmake" version = "0.1.58" @@ -2395,49 +2204,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cmov" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width 0.1.14", -] - -[[package]] -name = "color-print" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa954171903797d5623e047d9ab69d91b493657917bdfb8c2c80ecaf9cdb6f4" -dependencies = [ - "color-print-proc-macro", -] - -[[package]] -name = "color-print-proc-macro" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692186b5ebe54007e45a59aea47ece9eb4108e141326c304cdc91699a7118a22" -dependencies = [ - "nom 7.1.3", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" version = "1.0.5" @@ -2464,6 +2230,19 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -2498,12 +2277,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - [[package]] name = "const-random" version = "0.1.18" @@ -2624,17 +2397,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.17" @@ -2788,15 +2550,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-common" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" -dependencies = [ - "hybrid-array", -] - [[package]] name = "csv" version = "1.3.1" @@ -2827,15 +2580,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "ctutils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" -dependencies = [ - "cmov", -] - [[package]] name = "curl-sys" version = "0.4.88+curl-8.20.0" @@ -2848,7 +2592,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2861,7 +2605,7 @@ dependencies = [ "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", - "fiat-crypto 0.2.9", + "fiat-crypto", "rustc_version 0.4.1", "subtle", "zeroize", @@ -2878,17 +2622,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "d3d12" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28bfe653d79bd16c77f659305b195b82bb5ce0c0eb2a4846b82ddbd77586813" -dependencies = [ - "bitflags 2.9.4", - "libloading 0.8.9", - "winapi", -] - [[package]] name = "darling" version = "0.13.4" @@ -3063,19 +2796,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -3165,7 +2885,7 @@ checksum = "61fe34f401bd03724a1f96d12108144f8cd495a3cdda2bf5e091822fb80b7e66" dependencies = [ "arrow", "async-trait", - "dashmap 6.1.0", + "dashmap", "datafusion-common", "datafusion-common-runtime", "datafusion-datasource", @@ -3371,7 +3091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06f004d100f49a3658c9da6fb0c3a9b760062d96cd4ad82ccc3b7b69a9fb2f84" dependencies = [ "arrow", - "dashmap 6.1.0", + "dashmap", "datafusion-common", "datafusion-expr", "futures", @@ -3667,7 +3387,7 @@ checksum = "ad229a134c7406c057ece00c8743c0c34b97f4e72f78b475fe17b66c5e14fa4f" dependencies = [ "arrow", "async-trait", - "dashmap 6.1.0", + "dashmap", "datafusion-common", "datafusion-common-runtime", "datafusion-execution", @@ -3724,19 +3444,18 @@ dependencies = [ [[package]] name = "deno_ast" -version = "0.44.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc7aaabfdb3ddcad32aee1b62d250149dc8b35dfbdccbb125df2bdc62da952" +checksum = "c72e0409b3dbd60a5bf296cbc273a8e36bb3a3aab6abac389f1891e187d5ce14" dependencies = [ - "base64 0.21.7", - "deno_error", + "base64 0.22.1", + "capacity_builder", + "deno_error 0.7.3", "deno_media_type", "deno_terminal", "dprint-swc-ext", - "once_cell", "percent-encoding", "serde", - "sourcemap 9.3.2", "swc_atoms", "swc_common", "swc_config", @@ -3744,6 +3463,7 @@ dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", "swc_ecma_codegen_macros", + "swc_ecma_lexer", "swc_ecma_loader", "swc_ecma_parser", "swc_ecma_transforms_base", @@ -3756,146 +3476,45 @@ dependencies = [ "swc_ecma_visit", "swc_eq_ignore_macros", "swc_macros_common", + "swc_sourcemap", "swc_visit", - "swc_visit_macros", "text_lines", "thiserror 2.0.18", - "unicode-width 0.1.14", - "url", -] - -[[package]] -name = "deno_broadcast_channel" -version = "0.184.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33db5dacb54c6fda4c5ea4103c5687b76a51202343379af8b21120ba9d20f3c2" -dependencies = [ - "async-trait", - "deno_core", - "deno_error", - "thiserror 2.0.18", - "tokio", - "uuid", -] - -[[package]] -name = "deno_cache" -version = "0.122.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0daca6ec4e6142a994d38e7bc587dda7948fa00e6194b671a5d4340f5a918a3" -dependencies = [ - "async-trait", - "deno_core", - "deno_error", - "rusqlite", - "serde", - "sha2 0.10.9", - "thiserror 2.0.18", - "tokio", -] - -[[package]] -name = "deno_cache_dir" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27429da4d0e601baaa41415a43468d49a586645d13497f12e8a9346f9f6b1347" -dependencies = [ - "async-trait", - "base32", - "base64 0.21.7", - "boxed_error", - "cache_control", - "chrono", - "data-url", - "deno_error", - "deno_media_type", - "deno_path_util", - "http 1.4.0", - "indexmap 2.14.0", - "log", - "once_cell", - "parking_lot", - "serde", - "serde_json", - "sha2 0.10.9", - "sys_traits", - "thiserror 1.0.69", - "url", -] - -[[package]] -name = "deno_canvas" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ca8f93d60d96d6f6cb0da632303afb98567accf07d9b6f8d2ef88617589d9e" -dependencies = [ - "deno_core", - "deno_error", - "deno_webgpu", - "image", - "serde", - "thiserror 2.0.18", -] - -[[package]] -name = "deno_config" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08fe512a72c4300bd997c6849450a1f050da0c909a2a4fbdc44891647392bacf" -dependencies = [ - "boxed_error", - "capacity_builder 0.5.0", - "deno_error", - "deno_package_json", - "deno_path_util", - "deno_semver", - "glob", - "ignore", - "import_map", - "indexmap 2.14.0", - "jsonc-parser", - "log", - "percent-encoding", - "phf 0.11.3", - "serde", - "serde_json", - "sys_traits", - "thiserror 2.0.18", + "unicode-width 0.2.2", "url", ] [[package]] name = "deno_console" -version = "0.190.0" +version = "0.209.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94352b8d75c288a26ef748ad0ddae07e181109374a02c547850f96eef76b5389" +checksum = "66c0b8a65dcb7b38c22e5969c6454b3cb0839b7dcfb7a4f0d904de871a4c4416" dependencies = [ "deno_core", ] [[package]] name = "deno_core" -version = "0.336.0" +version = "0.352.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd50476c4325d5fa52bb906804a1e35b127d2a1dcf674e3447b53dcf25525bf" +checksum = "bf78f3f72ac8e09b18a588bc26a1b3c5ab853e7fb489889b2f5000654d34db5d" dependencies = [ "anyhow", "az", "bincode", - "bit-set 0.5.3", - "bit-vec 0.6.3", + "bit-set", + "bit-vec 0.8.0", "bytes", - "capacity_builder 0.1.3", + "capacity_builder", "cooked-waker", "deno_core_icudata", - "deno_error", + "deno_error 0.6.1", "deno_ops", "deno_path_util", "deno_unsync", "futures", "indexmap 2.14.0", "libc", - "memoffset", "parking_lot", "percent-encoding", "pin-project", @@ -3903,7 +3522,7 @@ dependencies = [ "serde_json", "serde_v8", "smallvec", - "sourcemap 8.0.1", + "sourcemap", "static_assertions", "thiserror 2.0.18", "tokio", @@ -3918,69 +3537,13 @@ version = "0.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" -[[package]] -name = "deno_cron" -version = "0.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ec283bef14bcf655b209619766bdeab67f2a5e093991cca73f5d502f7bf6e8" -dependencies = [ - "anyhow", - "async-trait", - "chrono", - "deno_core", - "deno_error", - "saffron", - "thiserror 2.0.18", - "tokio", -] - -[[package]] -name = "deno_crypto" -version = "0.204.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0493142a437e49b46aa8e08d715942076ff48c3cb776f0b015b4224ed0d37a" -dependencies = [ - "aes 0.8.3", - "aes-gcm", - "aes-kw", - "base64 0.21.7", - "cbc", - "const-oid 0.9.6", - "ctr", - "curve25519-dalek", - "deno_core", - "deno_error", - "deno_web", - "ed448-goldilocks", - "elliptic-curve", - "num-traits", - "once_cell", - "p256", - "p384", - "p521", - "rand 0.8.5", - "ring 0.17.14", - "rsa", - "sec1", - "serde", - "serde_bytes", - "sha1", - "sha2 0.10.9", - "signature", - "spki", - "thiserror 2.0.18", - "tokio", - "uuid", - "x25519-dalek", -] - [[package]] name = "deno_error" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c23dbc46d5804814b08b4675838f9884e3a52916987ec5105af36d42f9911b5" +checksum = "612ec3fc481fea759141b0c57810889b0a4fb6fee8f10748677bfe492fd30486" dependencies = [ - "deno_error_macro", + "deno_error_macro 0.6.1", "libc", "serde", "serde_json", @@ -3989,10 +3552,20 @@ dependencies = [ ] [[package]] -name = "deno_error_macro" -version = "0.5.5" +name = "deno_error" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babccedee31ce7e57c3e6dff2cb3ab8d68c49d0df8222fe0d11d628e65192790" +checksum = "3007d3f1ea92ea503324ae15883aac0c2de2b8cf6fead62203ff6a67161007ab" +dependencies = [ + "deno_error_macro 0.7.3", + "libc", +] + +[[package]] +name = "deno_error_macro" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8380a4224d5d2c3f84da4d764c4326cac62e9a1e3d4960442d29136fc07be863" dependencies = [ "proc-macro2", "quote", @@ -4000,16 +3573,38 @@ dependencies = [ ] [[package]] -name = "deno_fetch" -version = "0.214.0" +name = "deno_error_macro" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df032ca1f7f06a5cc459189b960793f64d415ddc9f59f262e0ad5059865002d" +checksum = "9b565e60a9685cdf312c888665b5f8647ac692a7da7e058a5e2268a466da8eaf" dependencies = [ - "base64 0.21.7", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "deno_features" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487773bb24b92f3b88d1c9ef0d4d15888641a2e2ea4d4cdfd6fda12cae26317c" +dependencies = [ + "deno_core", + "serde", + "serde_json", +] + +[[package]] +name = "deno_fetch" +version = "0.233.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbe158bec955790105ded69978b1245b97c65092f7bf184add344c0e78efffa" +dependencies = [ + "base64 0.22.1", "bytes", "data-url", "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_fs", "deno_path_util", "deno_permissions", @@ -4033,45 +3628,23 @@ dependencies = [ "tokio-rustls 0.26.4", "tokio-socks", "tokio-util", + "tokio-vsock", "tower 0.5.3", "tower-http", "tower-service", ] -[[package]] -name = "deno_ffi" -version = "0.177.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfbdc4e55c79ec1bc8a3ac72313e6f70d76340222f1e50c5c91e050296f83544" -dependencies = [ - "deno_core", - "deno_error", - "deno_permissions", - "dlopen2 0.6.1", - "dynasmrt", - "libffi", - "libffi-sys", - "log", - "num-bigint", - "serde", - "serde-value", - "serde_json", - "thiserror 2.0.18", - "tokio", - "winapi", -] - [[package]] name = "deno_fs" -version = "0.100.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82f79b71403b93b248727a89746026104b3a5ac1d82e79a02af6fa8e8487666" +checksum = "5ca83a95cea7bcdf19dac1888ef6f04aff69d251640a4d085bc6089c06b4b181" dependencies = [ "async-trait", "base32", "boxed_error", "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_io", "deno_path_util", "deno_permissions", @@ -4087,58 +3660,21 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "deno_http" -version = "0.188.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b7e7a3bcac31ebd4677a96318003a98f0fda4613f6ba6d7f5ba57928727191" -dependencies = [ - "async-compression", - "async-trait", - "base64 0.21.7", - "brotli 6.0.0", - "bytes", - "cache_control", - "deno_core", - "deno_error", - "deno_net", - "deno_websocket", - "flate2", - "http 0.2.12", - "http 1.4.0", - "httparse", - "hyper 0.14.32", - "hyper 1.9.0", - "hyper-util", - "itertools 0.10.5", - "memmem", - "mime", - "once_cell", - "percent-encoding", - "phf 0.11.3", - "pin-project", - "ring 0.17.14", - "scopeguard", - "serde", - "smallvec", - "thiserror 2.0.18", - "tokio", - "tokio-util", -] - [[package]] name = "deno_io" -version = "0.100.0" +version = "0.119.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e72489fe0dcada08047611d1ab92db1baebf7b606ab7c78790f622ecb30e22b" +checksum = "597aac25be261a1bd545d6f47a80439c60e600c076f9847b3718a592883b2a73" dependencies = [ "async-trait", "deno_core", - "deno_error", + "deno_error 0.6.1", + "deno_subprocess_windows", "filetime", "fs3", "libc", "log", + "nix 0.27.1", "once_cell", "os_pipe", "parking_lot", @@ -4150,88 +3686,24 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "deno_kv" -version = "0.98.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0e3930d0195a3350c05eb9a4bc619ec598ea84ad8bdb9b6c3e4bef798e7cf34" -dependencies = [ - "anyhow", - "async-trait", - "base64 0.21.7", - "boxed_error", - "bytes", - "chrono", - "deno_core", - "deno_error", - "deno_fetch", - "deno_path_util", - "deno_permissions", - "deno_tls", - "denokv_proto", - "denokv_remote", - "denokv_sqlite", - "faster-hex", - "http 1.4.0", - "http-body-util", - "log", - "num-bigint", - "prost", - "prost-build", - "rand 0.8.5", - "rusqlite", - "serde", - "thiserror 2.0.18", - "url", -] - -[[package]] -name = "deno_lockfile" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632e835a53ed667d62fdd766c5780fe8361c831d3e3fbf1a760a0b7896657587" -dependencies = [ - "deno_semver", - "serde", - "serde_json", - "thiserror 2.0.18", -] - [[package]] name = "deno_media_type" -version = "0.2.5" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600222d059ab31ff31182b3e12615df2134a9e01605836b78ad8df91ba39eab3" +checksum = "9fd0af4161f90b092feb363864a64d7c74e0efc13a15905d0d09df73bb72a123" dependencies = [ "data-url", "serde", "url", ] -[[package]] -name = "deno_napi" -version = "0.121.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f30bf147cc46dba87e3088d037cf99a2845ead1138033d3b346178cb781558" -dependencies = [ - "deno_core", - "deno_error", - "deno_permissions", - "libc", - "libloading 0.7.4", - "log", - "napi_sym", - "thiserror 2.0.18", - "windows-sys 0.59.0", -] - [[package]] name = "deno_native_certs" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bc737e098a45aa5742d51ce694ac7236a1e69fb0d9df8c862e9b4c9583c5f9" dependencies = [ - "dlopen2 0.7.0", + "dlopen2", "dlopen2_derive", "once_cell", "rustls-native-certs 0.7.3", @@ -4240,12 +3712,13 @@ dependencies = [ [[package]] name = "deno_net" -version = "0.182.0" +version = "0.201.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab869063cbfe428a707511835865d55247886eb175659e538af4d5096c3d4d9d" +checksum = "eb88f1ea2762065d6cc0316372acc22696ab6004943aa029f80546f9faf1b491" dependencies = [ "deno_core", - "deno_error", + "deno_error 0.6.1", + "deno_features", "deno_permissions", "deno_tls", "hickory-proto", @@ -4254,191 +3727,39 @@ dependencies = [ "quinn", "rustls-tokio-stream", "serde", + "sha2 0.10.9", "socket2 0.5.10", "thiserror 2.0.18", "tokio", -] - -[[package]] -name = "deno_node" -version = "0.128.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9638e803a668b0a5793ff94c9b2e82c54a05d9fc510901e9f3093d2d63dbdaab" -dependencies = [ - "aead-gcm-stream", - "aes 0.8.3", - "async-trait", - "base64 0.21.7", - "blake2", - "boxed_error", - "brotli 6.0.0", - "bytes", - "cbc", - "const-oid 0.9.6", - "ctr", - "data-encoding", - "deno_core", - "deno_error", - "deno_fetch", - "deno_fs", - "deno_io", - "deno_net", - "deno_package_json", - "deno_path_util", - "deno_permissions", - "deno_process", - "deno_whoami", - "der", - "digest 0.10.7", - "dsa", - "ecb", - "ecdsa", - "ed25519-dalek", - "elliptic-curve", - "errno", - "faster-hex", - "h2 0.4.14", - "hkdf", - "http 1.4.0", - "http-body-util", - "hyper 1.9.0", - "hyper-util", - "idna", - "indexmap 2.14.0", - "ipnetwork", - "k256", - "lazy-regex", - "libc", - "libz-sys", - "md-5 0.10.6", - "md4", - "memchr", - "node_resolver", - "num-bigint", - "num-bigint-dig", - "num-integer", - "num-traits", - "once_cell", - "p224", - "p256", - "p384", - "path-clean", - "pbkdf2", - "pkcs8", - "rand 0.8.5", - "regex", - "ring 0.17.14", - "ripemd", - "rsa", - "scrypt", - "sec1", - "serde", - "sha1", - "sha2 0.10.9", - "sha3", - "signature", - "simd-json", - "sm3", - "spki", - "stable_deref_trait", - "sys_traits", - "thiserror 2.0.18", - "tokio", - "tokio-eld", - "url", - "webpki-root-certs 0.26.11", - "winapi", - "windows-sys 0.59.0", - "x25519-dalek", - "x509-parser 0.15.1", - "yoke 0.7.5", -] - -[[package]] -name = "deno_npm" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adceb4c34f10e837d0e3ae76e88dddefb13e83c05c1ef1699fa5519241c9d27" -dependencies = [ - "async-trait", - "capacity_builder 0.5.0", - "deno_error", - "deno_lockfile", - "deno_semver", - "futures", - "log", - "monch", - "serde", - "serde_json", - "thiserror 2.0.18", + "tokio-vsock", "url", + "web-transport-proto", ] [[package]] name = "deno_ops" -version = "0.212.0" +version = "0.228.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d328067139909aa81522a5d90f119368b541fbddd73ab630e4d9f777865f0d" +checksum = "8bf8dbe5abf37d270bb853c5dfe45fbe3b1b6c453877cc11d7fe84e9862a6dbc" dependencies = [ "indexmap 2.14.0", "proc-macro-rules", "proc-macro2", "quote", "stringcase", - "strum 0.25.0", - "strum_macros 0.25.3", + "strum 0.27.2", + "strum_macros 0.27.2", "syn 2.0.117", "thiserror 2.0.18", ] -[[package]] -name = "deno_os" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8371d206f6265c4e0b74116c1a58cc8c464c45da0b43c1e8c19a911e88feb2b" -dependencies = [ - "deno_core", - "deno_error", - "deno_path_util", - "deno_permissions", - "deno_telemetry", - "libc", - "netif", - "ntapi", - "once_cell", - "serde", - "signal-hook", - "signal-hook-registry", - "thiserror 2.0.18", - "tokio", - "winapi", -] - -[[package]] -name = "deno_package_json" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07d26dbfcc01e636aef86f9baff7faf5338398e74d283d8fe01e39068f48049" -dependencies = [ - "boxed_error", - "deno_error", - "deno_path_util", - "deno_semver", - "indexmap 2.14.0", - "serde", - "serde_json", - "sys_traits", - "thiserror 2.0.18", - "url", -] - [[package]] name = "deno_path_util" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87b8996966ae1b13ee9c20219b1d10fc53905b9570faae6adfa34614fd15224" +checksum = "516f813389095889776b81cc9108ff6f336fd9409b4b12fc0138aea23d2708e1" dependencies = [ - "deno_error", + "deno_error 0.6.1", "percent-encoding", "sys_traits", "thiserror 2.0.18", @@ -4447,183 +3768,54 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.49.0" +version = "0.68.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf879dff0b3de4dbcb78d6dda3a55e711369d5b9f479270a82853ef106c4176" +checksum = "baa14d9c3fbba59836ffbaac7f736a2f48d4a5fc209a2103d1e1b898915232a5" dependencies = [ - "capacity_builder 0.5.0", - "deno_core", - "deno_error", + "capacity_builder", + "deno_error 0.6.1", "deno_path_util", "deno_terminal", + "deno_unsync", "fqdn", + "ipnetwork", "libc", "log", - "once_cell", - "percent-encoding", - "serde", - "thiserror 2.0.18", - "which 6.0.3", - "winapi", -] - -[[package]] -name = "deno_process" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "700f8a2c9d369e7035e693f26a671489a73724450cbbc0a1e32f3966ef2f21fb" -dependencies = [ - "deno_core", - "deno_error", - "deno_fs", - "deno_io", - "deno_os", - "deno_path_util", - "deno_permissions", - "libc", - "log", - "memchr", "nix 0.27.1", - "pin-project-lite", - "rand 0.8.5", - "serde", - "simd-json", - "tempfile", - "thiserror 2.0.18", - "tokio", - "which 6.0.3", - "winapi", - "windows-sys 0.59.0", -] - -[[package]] -name = "deno_resolver" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c4ceec7b6e22344047b8a5577bb8239dc0a99884c25c1fa7d8611f4c3ed28b" -dependencies = [ - "anyhow", - "async-once-cell", - "async-trait", - "base32", - "boxed_error", - "dashmap 5.5.3", - "deno_cache_dir", - "deno_config", - "deno_error", - "deno_media_type", - "deno_npm", - "deno_package_json", - "deno_path_util", - "deno_semver", - "deno_terminal", - "futures", - "log", - "node_resolver", "once_cell", "parking_lot", + "percent-encoding", + "serde", + "serde_json", "sys_traits", + "temp_deno_which", "thiserror 2.0.18", "url", -] - -[[package]] -name = "deno_runtime" -version = "0.198.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a54d54ca920e5256c1e910c7574787d009a34afd41b20ad250278bb1aea290" -dependencies = [ - "color-print", - "deno_ast", - "deno_broadcast_channel", - "deno_cache", - "deno_canvas", - "deno_console", - "deno_core", - "deno_cron", - "deno_crypto", - "deno_error", - "deno_fetch", - "deno_ffi", - "deno_fs", - "deno_http", - "deno_io", - "deno_kv", - "deno_napi", - "deno_net", - "deno_node", - "deno_os", - "deno_path_util", - "deno_permissions", - "deno_process", - "deno_resolver", - "deno_telemetry", - "deno_terminal", - "deno_tls", - "deno_url", - "deno_web", - "deno_webgpu", - "deno_webidl", - "deno_websocket", - "deno_webstorage", - "dlopen2 0.6.1", - "encoding_rs", - "fastwebsockets", - "http 1.4.0", - "http-body-util", - "hyper 0.14.32", - "hyper 1.9.0", - "hyper-util", - "libc", - "log", - "nix 0.27.1", - "node_resolver", - "notify", - "ntapi", - "once_cell", - "percent-encoding", - "regex", - "rustyline", - "same-file", - "serde", - "sys_traits", - "tempfile", - "thiserror 2.0.18", - "tokio", - "tokio-metrics", - "twox-hash 1.6.3", - "uuid", - "which 6.0.3", "winapi", "windows-sys 0.59.0", ] [[package]] -name = "deno_semver" -version = "0.7.1" +name = "deno_subprocess_windows" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4775271f9b5602482698f76d24ea9ed8ba27af7f587a7e9a876916300c542435" +checksum = "7bc6b10059f0ccb14c6e0319c5275f0407fb2f9ffe405cd555700561999ea4bf" dependencies = [ - "capacity_builder 0.5.0", - "deno_error", - "ecow", - "hipstr", - "monch", - "once_cell", - "serde", - "thiserror 2.0.18", - "url", + "fastrand", + "futures-channel", + "libc", + "windows-sys 0.59.0", ] [[package]] name = "deno_telemetry" -version = "0.12.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73802ee27361bbb6c0e3c04a799b39f458afbed1972c4aff0867420d1c36fdb" +checksum = "377581966bd34e85ce230f7f4b1dee7e16c6bf7f845b4690648507ce7ba105d9" dependencies = [ "async-trait", "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_tls", "http-body-util", "hyper 1.9.0", @@ -4644,9 +3836,9 @@ dependencies = [ [[package]] name = "deno_terminal" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ba8041ae7319b3ca6a64c399df4112badcbbe0868b4517637647614bede4be" +checksum = "23f71c27009e0141dedd315f1dfa3ebb0a6ca4acce7c080fac576ea415a465f6" dependencies = [ "once_cell", "termcolor", @@ -4654,12 +3846,12 @@ dependencies = [ [[package]] name = "deno_tls" -version = "0.177.0" +version = "0.196.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e3ceb2be448150d8214e8fc454c947e0ea94f6ce16556544f05a67ad5a16b8" +checksum = "a7835eb6a8d114703b0293573fbb8885bc2c81e8c35363b9e89391dd3c541fa6" dependencies = [ "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_native_certs", "rustls 0.23.35", "rustls-pemfile 2.2.0", @@ -4684,27 +3876,26 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.190.0" +version = "0.209.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79e743ad841f7826d46c6944580f5ba665fe9ab4c31a68c4eed8b5a78225da3" +checksum = "8cccbb10fb59f29b04161055a65f7fe83364f9e8317d4d2ce3bd7979faf63a87" dependencies = [ "deno_core", - "deno_error", - "thiserror 2.0.18", + "deno_error 0.6.1", "urlpattern", ] [[package]] name = "deno_web" -version = "0.221.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8041ba73bb2f238c61b5e4ed341d2fe1f9464a71115a240ab3390480b3c10e12" +checksum = "1d6b8a97cc90b6aaea20fe200cfa7e5b6953dd33ecda0af50d6d360387c33df4" dependencies = [ "async-trait", - "base64-simd 0.8.0", + "base64-simd", "bytes", "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_permissions", "encoding_rs", "flate2", @@ -4715,197 +3906,40 @@ dependencies = [ "uuid", ] -[[package]] -name = "deno_webgpu" -version = "0.157.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4077584c0ccfde0737e576c396bbf1645f25ed0ebf4f44543e0ad13729285cf3" -dependencies = [ - "deno_core", - "deno_error", - "raw-window-handle", - "serde", - "thiserror 2.0.18", - "tokio", - "wgpu-core", - "wgpu-types", -] - [[package]] name = "deno_webidl" -version = "0.190.0" +version = "0.209.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ff81a990196bf3a80fe5d339b4eb8b411ef17634d60d399a63bae6e71a37c9" +checksum = "a20bbfac0cf15918f7cbd0b55c366ac20ad65c825f362fa684c3104984254d3b" dependencies = [ "deno_core", ] -[[package]] -name = "deno_websocket" -version = "0.195.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad15c3856dd1748f9a36102e90b4e345e40d7d64a9bf6672d584201e1fded28" -dependencies = [ - "bytes", - "deno_core", - "deno_error", - "deno_net", - "deno_permissions", - "deno_tls", - "fastwebsockets", - "h2 0.4.14", - "http 1.4.0", - "http-body-util", - "hyper 1.9.0", - "hyper-util", - "once_cell", - "rustls-tokio-stream", - "serde", - "thiserror 2.0.18", - "tokio", -] - -[[package]] -name = "deno_webstorage" -version = "0.185.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079dc4f6ce91f53bb848bad8d743dc20d16ca44cbed3425531cf5d922b1a45bc" -dependencies = [ - "deno_core", - "deno_error", - "deno_web", - "rusqlite", - "thiserror 2.0.18", -] - -[[package]] -name = "deno_whoami" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75e4caa92b98a27f09c671d1399aee0f5970aa491b9a598523aac000a2192e3" -dependencies = [ - "libc", - "whoami", -] - -[[package]] -name = "denokv_proto" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5b77de4d3b9215e14624d4f4eb16cb38c0810e3f5860ba3b3fc47d0537f9a4d" -dependencies = [ - "async-trait", - "chrono", - "deno_error", - "futures", - "num-bigint", - "prost", - "serde", - "uuid", -] - -[[package]] -name = "denokv_remote" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6497c28eec268ed99f1e8664f0842935f02d1508529c67d94c57ca5d893d743" -dependencies = [ - "async-stream", - "async-trait", - "bytes", - "chrono", - "deno_error", - "denokv_proto", - "futures", - "http 1.4.0", - "log", - "prost", - "rand 0.8.5", - "serde", - "serde_json", - "thiserror 2.0.18", - "tokio", - "tokio-util", - "url", - "uuid", -] - -[[package]] -name = "denokv_sqlite" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0f21a450a35eb85760761401fddf9bfff9840127be07a6ca5c31863127913d" -dependencies = [ - "async-stream", - "async-trait", - "chrono", - "deno_error", - "denokv_proto", - "futures", - "hex", - "log", - "num-bigint", - "rand 0.8.5", - "rusqlite", - "serde_json", - "thiserror 2.0.18", - "tokio", - "tokio-stream", - "uuid", - "v8_valueserializer", -] - [[package]] name = "der" version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid 0.9.6", - "der_derive", + "const-oid", "pem-rfc7468", "zeroize", ] -[[package]] -name = "der-parser" -version = "8.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" -dependencies = [ - "asn1-rs 0.5.2", - "displaydoc", - "nom 7.1.3", - "num-bigint", - "num-traits", - "rusticata-macros", -] - [[package]] name = "der-parser" version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", "displaydoc", - "nom 7.1.3", + "nom", "num-bigint", "num-traits", "rusticata-macros", ] -[[package]] -name = "der_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "deranged" version = "0.5.8" @@ -5047,23 +4081,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "const-oid 0.9.6", - "crypto-common 0.1.7", + "const-oid", + "crypto-common", "subtle", ] -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer 0.12.0", - "const-oid 0.10.2", - "crypto-common 0.2.1", - "ctutils", -] - [[package]] name = "dirs" version = "4.0.0" @@ -5133,7 +4155,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5158,18 +4180,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "dlopen2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bc2c7ed06fd72a8513ded8d0d2f6fd2655a85d6885c48cae8625d80faf28c03" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] - [[package]] name = "dlopen2" version = "0.7.0" @@ -5193,15 +4203,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -5222,35 +4223,20 @@ checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" [[package]] name = "dprint-swc-ext" -version = "0.20.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba28c12892aadb751c2ba7001d8460faee4748a04b4edc51c7121cc67ee03db" +checksum = "cf592ae6a864437e98ef9c6ae7936b822077e9d038a3a48ee081ab92313afad4" dependencies = [ "num-bigint", - "rustc-hash 1.1.0", + "rustc-hash 2.1.2", "swc_atoms", "swc_common", "swc_ecma_ast", + "swc_ecma_lexer", "swc_ecma_parser", "text_lines", ] -[[package]] -name = "dsa" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48bc224a9084ad760195584ce5abb3c2c34a225fa312a128ad245a6b412b7689" -dependencies = [ - "digest 0.10.7", - "num-bigint-dig", - "num-traits", - "pkcs8", - "rfc6979", - "sha2 0.10.9", - "signature", - "zeroize", -] - [[package]] name = "duct" version = "0.13.7" @@ -5291,41 +4277,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" -[[package]] -name = "dynasm" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" -dependencies = [ - "bitflags 1.3.2", - "byteorder", - "lazy_static", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "dynasmrt" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" -dependencies = [ - "byteorder", - "dynasm", - "memmap2 0.5.10", -] - -[[package]] -name = "ecb" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a8bfa975b1aec2145850fcaa1c6fe269a16578c44705a532ae3edc92b8881c7" -dependencies = [ - "cipher 0.4.4", -] - [[package]] name = "ecdsa" version = "0.16.9" @@ -5340,15 +4291,6 @@ dependencies = [ "spki", ] -[[package]] -name = "ecow" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78e4f79b296fbaab6ce2e22d52cb4c7f010fe0ebe7a32e34fa25885fd797bd02" -dependencies = [ - "serde", -] - [[package]] name = "ed25519" version = "2.2.3" @@ -5375,18 +4317,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ed448-goldilocks" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06924531e9e90130842b012e447f85bdaf9161bc8a0f8092be8cb70b01ebe092" -dependencies = [ - "fiat-crypto 0.1.20", - "hex", - "subtle", - "zeroize", -] - [[package]] name = "educe" version = "0.6.0" @@ -5415,7 +4345,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", - "base64ct", "crypto-bigint", "digest 0.10.7", "ff", @@ -5426,8 +4355,6 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "sec1", - "serde_json", - "serdect", "subtle", "zeroize", ] @@ -5440,19 +4367,13 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - [[package]] name = "enum-as-inner" version = "0.6.1" @@ -5529,15 +4450,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] -[[package]] -name = "error-code" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" - [[package]] name = "error_reporter" version = "1.0.0" @@ -5598,7 +4513,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" dependencies = [ "futures-core", - "nom 7.1.3", + "nom", "pin-project-lite", ] @@ -5608,25 +4523,13 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fancy-regex" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" dependencies = [ - "bit-set 0.8.0", + "bit-set", "regex-automata", "regex-syntax 0.8.10", ] @@ -5637,7 +4540,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8" dependencies = [ - "bit-set 0.8.0", + "bit-set", "regex-automata", "regex-syntax 0.8.10", ] @@ -5648,61 +4551,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" -dependencies = [ - "serde", -] - [[package]] name = "fastrand" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" -[[package]] -name = "fastwebsockets" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dac026e15fb7e44d768880b868a0fd5bd30ffdee272e88b3060f657a5a72947" -dependencies = [ - "base64 0.21.7", - "bytes", - "http-body-util", - "hyper 1.9.0", - "hyper-util", - "pin-project", - "rand 0.8.5", - "sha1", - "simdutf8", - "thiserror 1.0.69", - "tokio", - "utf-8", -] - -[[package]] -name = "fd-lock" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" -dependencies = [ - "cfg-if", - "rustix 1.1.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - [[package]] name = "ff" version = "0.13.1" @@ -5713,12 +4567,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "fiat-crypto" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" - [[package]] name = "fiat-crypto" version = "0.2.9" @@ -5766,19 +4614,10 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "libz-sys", - "miniz_oxide 0.8.9", + "miniz_oxide", "zlib-rs", ] -[[package]] -name = "float-cmp" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" -dependencies = [ - "num-traits", -] - [[package]] name = "float8" version = "0.6.1" @@ -5827,28 +4666,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared 0.1.1", -] - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared 0.3.1", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "foreign-types-shared", ] [[package]] @@ -5857,12 +4675,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -5880,11 +4692,10 @@ checksum = "eb540cf7bc4fe6df9d8f7f0c974cfd0dce8ed4e9e8884e73433b503ee78b4e7d" [[package]] name = "from_variant" -version = "0.1.9" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4" +checksum = "308530a56b099da144ebc5d8e179f343ad928fa2b3558d1eb3db9af18d6eff43" dependencies = [ - "proc-macro2", "swc_macros_common", "syn 2.0.117", ] @@ -5916,15 +4727,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "fsevent-sys" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" -dependencies = [ - "libc", -] - [[package]] name = "fslock" version = "0.2.1" @@ -6208,8 +5010,8 @@ dependencies = [ "libc", "log", "rustversion", - "windows-link 0.2.1", - "windows-result 0.4.1", + "windows-link 0.1.3", + "windows-result 0.3.4", ] [[package]] @@ -6289,7 +5091,6 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "rand_core 0.10.1", "wasip2", "wasip3", ] @@ -6330,17 +5131,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - [[package]] name = "glob" version = "0.3.3" @@ -6372,27 +5162,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "glow" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" -dependencies = [ - "gl_generator", -] - [[package]] name = "google-cloud-auth" version = "0.17.2" @@ -6493,45 +5262,6 @@ dependencies = [ "unic-ucd-category", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.9.4", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.9.4", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.9.4", - "gpu-descriptor-types", - "hashbrown 0.15.5", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.9.4", -] - [[package]] name = "group" version = "0.13.0" @@ -6605,16 +5335,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "halfbrown" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" -dependencies = [ - "hashbrown 0.14.5", - "serde", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -6675,15 +5395,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "hashlink" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" -dependencies = [ - "hashbrown 0.14.5", -] - [[package]] name = "hashlink" version = "0.10.0" @@ -6693,20 +5404,6 @@ dependencies = [ "hashbrown 0.15.5", ] -[[package]] -name = "hdrhistogram" -version = "7.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" -dependencies = [ - "base64 0.21.7", - "byteorder", - "crossbeam-channel", - "flate2", - "nom 7.1.3", - "num-traits", -] - [[package]] name = "headers" version = "0.4.1" @@ -6755,12 +5452,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - [[package]] name = "hf-hub" version = "0.4.3" @@ -6833,24 +5524,13 @@ dependencies = [ "tracing", ] -[[package]] -name = "hipstr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97971ffc85d4c98de12e2608e992a43f5294ebb625fdb045b27c731b64c4c6d6" -dependencies = [ - "serde", - "serde_bytes", - "sptr", -] - [[package]] name = "hkdf" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac 0.12.1", + "hmac", ] [[package]] @@ -6862,15 +5542,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "hmac" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" -dependencies = [ - "digest 0.11.3", -] - [[package]] name = "home" version = "0.5.12" @@ -6893,15 +5564,14 @@ dependencies = [ [[package]] name = "hstr" -version = "0.2.17" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a26def229ea95a8709dad32868d975d0dd40235bd2ce82920e4a8fe692b5e0" +checksum = "31f11d91d7befd2ffd9d216e9e5ea1fae6174b20a2a1b67a688138003d2f4122" dependencies = [ "hashbrown 0.14.5", "new_debug_unreachable", "once_cell", - "phf 0.11.3", - "rustc-hash 1.1.0", + "rustc-hash 2.1.2", "triomphe", ] @@ -7013,15 +5683,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" -[[package]] -name = "hybrid-array" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" -dependencies = [ - "typenum", -] - [[package]] name = "hyper" version = "0.14.32" @@ -7255,7 +5916,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.56.0", ] [[package]] @@ -7276,7 +5937,7 @@ dependencies = [ "displaydoc", "potential_utf", "utf8_iter", - "yoke 0.8.2", + "yoke", "zerofrom", "zerovec", ] @@ -7343,7 +6004,7 @@ dependencies = [ "displaydoc", "icu_locale_core", "writeable", - "yoke 0.8.2", + "yoke", "zerofrom", "zerotrie", "zerovec", @@ -7388,52 +6049,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" -[[package]] -name = "ignore" -version = "0.4.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "image" -version = "0.24.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "num-traits", - "png", -] - -[[package]] -name = "import_map" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1215d4d92511fbbdaea50e750e91f2429598ef817f02b579158e92803b52c00a" -dependencies = [ - "boxed_error", - "deno_error", - "indexmap 2.14.0", - "log", - "percent-encoding", - "serde", - "serde_json", - "thiserror 2.0.18", - "url", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -7470,33 +6085,12 @@ dependencies = [ "web-time", ] -[[package]] -name = "inotify" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" -dependencies = [ - "bitflags 1.3.2", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - [[package]] name = "inout" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "block-padding 0.3.3", "generic-array", ] @@ -7696,15 +6290,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "jsonc-parser" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6d80e6d70e7911a29f3cf3f44f452df85d06f73572b494ca99a2cad3fcf8f4" -dependencies = [ - "serde_json", -] - [[package]] name = "jsonpath-rust" version = "0.7.5" @@ -7767,20 +6352,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "k256" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.9", - "signature", -] - [[package]] name = "k8s-openapi" version = "0.25.0" @@ -7793,15 +6364,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - [[package]] name = "keyed_priority_queue" version = "0.4.2" @@ -7811,23 +6373,6 @@ dependencies = [ "indexmap 2.14.0", ] -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading 0.8.9", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - [[package]] name = "konst" version = "0.2.20" @@ -7843,26 +6388,6 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" -[[package]] -name = "kqueue" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" -dependencies = [ - "kqueue-sys", - "libc", -] - -[[package]] -name = "kqueue-sys" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" -dependencies = [ - "bitflags 1.3.2", - "libc", -] - [[package]] name = "kube" version = "1.1.0" @@ -7979,29 +6504,6 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -[[package]] -name = "lazy-regex" -version = "3.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bae91019476d3ec7147de9aa291cadb6d870abf2f3015d2da73a90325ac1496" -dependencies = [ - "lazy-regex-proc_macros", - "once_cell", - "regex", -] - -[[package]] -name = "lazy-regex-proc_macros" -version = "3.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de9c1e1439d8b7b3061b2d209809f447ca33241733d9a3c01eabf2dc8d94358" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 2.0.117", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -8086,16 +6588,6 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "libffi" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" -dependencies = [ - "libc", - "libffi-sys", -] - [[package]] name = "libffi-sys" version = "2.3.0" @@ -8127,16 +6619,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.9" @@ -8182,7 +6664,6 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "cc", "pkg-config", "vcpkg", ] @@ -8244,12 +6725,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - [[package]] name = "lock_api" version = "0.4.14" @@ -8320,7 +6795,7 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" dependencies = [ - "twox-hash 2.1.2", + "twox-hash", ] [[package]] @@ -8477,15 +6952,6 @@ dependencies = [ "malachite-nz", ] -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "mappable-rc" version = "0.1.1" @@ -8540,25 +7006,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "md-5" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" -dependencies = [ - "cfg-if", - "digest 0.11.3", -] - -[[package]] -name = "md4" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da5ac363534dce5fabf69949225e174fbf111a498bf0ff794c8ea1fba9f3dda" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "md5" version = "0.6.1" @@ -8580,15 +7027,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" -[[package]] -name = "memmap2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.9.10" @@ -8599,12 +7037,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "memmem" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" - [[package]] name = "memoffset" version = "0.9.1" @@ -8614,21 +7046,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "metal" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" -dependencies = [ - "bitflags 2.9.4", - "block", - "core-graphics-types", - "foreign-types 0.5.0", - "log", - "objc", - "paste", -] - [[package]] name = "miette" version = "7.6.0" @@ -8689,15 +7106,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -8708,18 +7116,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - [[package]] name = "mio" version = "1.2.0" @@ -8751,12 +7147,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "monch" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" - [[package]] name = "monostate" version = "0.1.18" @@ -8796,12 +7186,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - [[package]] name = "murmurhash32" version = "0.3.1" @@ -8852,7 +7236,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-util", - "twox-hash 2.1.2", + "twox-hash", "url", ] @@ -8884,28 +7268,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "naga" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" -dependencies = [ - "arrayvec", - "bit-set 0.5.3", - "bitflags 2.9.4", - "codespan-reporting", - "hexf-parse", - "indexmap 2.14.0", - "log", - "num-traits", - "rustc-hash 1.1.0", - "serde", - "spirv", - "termcolor", - "thiserror 1.0.69", - "unicode-xid", -] - [[package]] name = "nanorand" version = "0.7.0" @@ -8915,18 +7277,6 @@ dependencies = [ "getrandom 0.2.17", ] -[[package]] -name = "napi_sym" -version = "0.120.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a55ec137cebb7f4a594edd16157a5b9d9addf7ebd29c88198ec4e0cff2e93e" -dependencies = [ - "quote", - "serde", - "serde_json", - "syn 2.0.117", -] - [[package]] name = "native-tls" version = "0.2.16" @@ -8944,40 +7294,12 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys 0.3.1", -] - -[[package]] -name = "netif" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29a01b9f018d6b7b277fef6c79fdbd9bf17bb2d1e298238055cafab49baa5ee" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - [[package]] name = "nix" version = "0.27.1" @@ -8997,7 +7319,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.9.4", "cfg-if", - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", ] @@ -9009,10 +7331,23 @@ checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags 2.9.4", "cfg-if", - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", ] +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + [[package]] name = "nkeys" version = "0.4.5" @@ -9028,42 +7363,6 @@ dependencies = [ "signatory", ] -[[package]] -name = "node_resolver" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808426e80ce77a311b24ac080caf18c23c632e035d797edb217ce74cdf6a0e71" -dependencies = [ - "anyhow", - "async-trait", - "boxed_error", - "dashmap 5.5.3", - "deno_error", - "deno_media_type", - "deno_package_json", - "deno_path_util", - "futures", - "lazy-regex", - "once_cell", - "path-clean", - "regex", - "serde", - "serde_json", - "sys_traits", - "thiserror 2.0.18", - "url", -] - -[[package]] -name = "nom" -version = "5.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" -dependencies = [ - "memchr", - "version_check", -] - [[package]] name = "nom" version = "7.1.3" @@ -9074,25 +7373,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "notify" -version = "6.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" -dependencies = [ - "bitflags 2.9.4", - "crossbeam-channel", - "filetime", - "fsevent-sys", - "inotify", - "kqueue", - "libc", - "log", - "mio 0.8.11", - "walkdir", - "windows-sys 0.48.0", -] - [[package]] name = "ntapi" version = "0.4.3" @@ -9108,7 +7388,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -9288,7 +7568,6 @@ dependencies = [ "num-iter", "num-traits", "rand 0.8.5", - "serde", "smallvec", "zeroize", ] @@ -9404,7 +7683,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "chrono", "getrandom 0.2.17", "http 1.4.0", @@ -9418,15 +7697,6 @@ dependencies = [ "url", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "object" version = "0.37.3" @@ -9482,22 +7752,13 @@ dependencies = [ "cc", ] -[[package]] -name = "oid-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" -dependencies = [ - "asn1-rs 0.5.2", -] - [[package]] name = "oid-registry" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", ] [[package]] @@ -9562,7 +7823,7 @@ dependencies = [ "chrono", "dyn-clone", "ed25519-dalek", - "hmac 0.12.1", + "hmac", "http 1.4.0", "itertools 0.10.5", "log", @@ -9591,7 +7852,7 @@ checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542" dependencies = [ "bitflags 2.9.4", "cfg-if", - "foreign-types 0.3.2", + "foreign-types", "libc", "openssl-macros", "openssl-sys", @@ -9804,6 +8065,8 @@ dependencies = [ "rand 0.8.5", "serde_json", "thiserror 1.0.69", + "tokio", + "tokio-stream", "tracing", ] @@ -9878,20 +8141,14 @@ dependencies = [ [[package]] name = "os_pipe" -version = "1.1.5" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] -[[package]] -name = "outref" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" - [[package]] name = "outref" version = "0.5.2" @@ -9912,18 +8169,6 @@ version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" -[[package]] -name = "p224" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.9", -] - [[package]] name = "p256" version = "0.13.2" @@ -9949,17 +8194,12 @@ dependencies = [ ] [[package]] -name = "p521" -version = "0.13.3" +name = "par-core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +checksum = "e96cbd21255b7fb29a5d51ef38a779b517a91abd59e2756c039583f43ef4c90f" dependencies = [ - "base16ct", - "ecdsa", - "elliptic-curve", - "primeorder", - "rand_core 0.6.4", - "sha2 0.10.9", + "once_cell", ] [[package]] @@ -10023,7 +8263,7 @@ dependencies = [ "snap", "thrift", "tokio", - "twox-hash 2.1.2", + "twox-hash", "zstd", ] @@ -10050,28 +8290,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5a797f0e07bdf071d15742978fc3128ec6c22891c31a3a931513263904c982a" -[[package]] -name = "path-clean" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" - [[package]] name = "pathdiff" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", -] - [[package]] name = "pem" version = "1.1.1" @@ -10199,6 +8423,16 @@ dependencies = [ "phf_shared 0.12.1", ] +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_shared 0.13.1", + "serde", +] + [[package]] name = "phf_codegen" version = "0.11.3" @@ -10250,6 +8484,15 @@ dependencies = [ "siphasher 1.0.3", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.3", +] + [[package]] name = "php-parser-rs" version = "0.1.3" @@ -10305,21 +8548,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pkcs5" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" -dependencies = [ - "aes 0.8.3", - "cbc", - "der", - "pbkdf2", - "scrypt", - "sha2 0.10.9", - "spki", -] - [[package]] name = "pkcs8" version = "0.10.2" @@ -10327,8 +8555,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", - "pkcs5", - "rand_core 0.6.4", "spki", ] @@ -10344,19 +8570,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide 0.8.9", -] - [[package]] name = "polyval" version = "0.6.2" @@ -10377,85 +8590,56 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "postgres-native-tls" -version = "0.5.0" -source = "git+https://github.com/imor/rust-postgres?rev=20265ef38e32a06f76b6f9b678e2077fc2211f6b#20265ef38e32a06f76b6f9b678e2077fc2211f6b" +version = "0.5.2" +source = "git+https://github.com/MaterializeInc/rust-postgres?rev=78c1222577bb091d69bc22b1bc7ad01c14675abe#78c1222577bb091d69bc22b1bc7ad01c14675abe" dependencies = [ "native-tls", "tokio", "tokio-native-tls", - "tokio-postgres 0.7.11", + "tokio-postgres", ] [[package]] name = "postgres-native-tls" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f39498473c92f7b6820ae970382c1d83178a3454c618161cb772e8598d9f6f" +checksum = "fef4de47bb81477e0c3deaf153a1b10ae176484713ff1640969f4cb96b653ebc" dependencies = [ "native-tls", "tokio", "tokio-native-tls", - "tokio-postgres 0.7.13", + "tokio-postgres", ] [[package]] name = "postgres-protocol" -version = "0.6.7" -source = "git+https://github.com/imor/rust-postgres?rev=20265ef38e32a06f76b6f9b678e2077fc2211f6b#20265ef38e32a06f76b6f9b678e2077fc2211f6b" +version = "0.6.9" +source = "git+https://github.com/MaterializeInc/rust-postgres?rev=78c1222577bb091d69bc22b1bc7ad01c14675abe#78c1222577bb091d69bc22b1bc7ad01c14675abe" dependencies = [ "base64 0.22.1", "byteorder", "bytes", - "fallible-iterator 0.2.0", - "hmac 0.12.1", + "fallible-iterator", + "hmac", "md-5 0.10.6", "memchr", - "rand 0.8.5", + "rand 0.9.0", "sha2 0.10.9", "stringprep", ] -[[package]] -name = "postgres-protocol" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56201207dac53e2f38e848e31b4b91616a6bb6e0c7205b77718994a7f49e70fc" -dependencies = [ - "base64 0.22.1", - "byteorder", - "bytes", - "fallible-iterator 0.2.0", - "hmac 0.13.0", - "md-5 0.11.0", - "memchr", - "rand 0.10.1", - "sha2 0.11.0", - "stringprep", -] - [[package]] name = "postgres-types" -version = "0.2.7" -source = "git+https://github.com/imor/rust-postgres?rev=20265ef38e32a06f76b6f9b678e2077fc2211f6b#20265ef38e32a06f76b6f9b678e2077fc2211f6b" -dependencies = [ - "bytes", - "fallible-iterator 0.2.0", - "postgres-protocol 0.6.7", -] - -[[package]] -name = "postgres-types" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613283563cd90e1dfc3518d548caee47e0e725455ed619881f5cf21f36de4b48" +version = "0.2.11" +source = "git+https://github.com/MaterializeInc/rust-postgres?rev=78c1222577bb091d69bc22b1bc7ad01c14675abe#78c1222577bb091d69bc22b1bc7ad01c14675abe" dependencies = [ "array-init", "bit-vec 0.6.3", "bytes", "chrono", - "fallible-iterator 0.2.0", - "postgres-protocol 0.6.11", - "serde", + "fallible-iterator", + "postgres-protocol", + "serde_core", "serde_json", "uuid", ] @@ -10527,7 +8711,6 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", "version_check", ] @@ -10635,12 +8818,6 @@ dependencies = [ "hex", ] -[[package]] -name = "profiling" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" - [[package]] name = "prometheus" version = "0.14.0" @@ -10665,26 +8842,6 @@ dependencies = [ "prost-derive", ] -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck 0.5.0", - "itertools 0.14.0", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.117", - "tempfile", -] - [[package]] name = "prost-derive" version = "0.13.5" @@ -10817,7 +8974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", - "cfg_aliases 0.2.1", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -10858,7 +9015,7 @@ version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", "once_cell", "socket2 0.6.3", @@ -10893,16 +9050,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - [[package]] name = "rand" version = "0.7.3" @@ -10938,17 +9085,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "rand" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" -dependencies = [ - "chacha20", - "getrandom 0.4.2", - "rand_core 0.10.1", -] - [[package]] name = "rand_chacha" version = "0.2.2" @@ -11006,12 +9142,6 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "rand_core" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" - [[package]] name = "rand_distr" version = "0.5.1" @@ -11031,12 +9161,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "range-alloc" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" - [[package]] name = "raw-cpuid" version = "11.6.0" @@ -11046,12 +9170,6 @@ dependencies = [ "bitflags 2.9.4", ] -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - [[package]] name = "rayon" version = "1.12.0" @@ -11093,7 +9211,7 @@ dependencies = [ "ring 0.17.14", "rustls-pki-types", "time", - "x509-parser 0.16.0", + "x509-parser", "yasna", ] @@ -11427,7 +9545,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac 0.12.1", + "hmac", "subtle", ] @@ -11460,15 +9578,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "rkyv" version = "0.7.46" @@ -11546,18 +9655,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "ron" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" -dependencies = [ - "base64 0.21.7", - "bitflags 2.9.4", - "serde", - "serde_derive", -] - [[package]] name = "rquickjs" version = "0.11.0" @@ -11612,7 +9709,7 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid 0.9.6", + "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", @@ -11646,20 +9743,6 @@ dependencies = [ "tokio-rustls 0.25.0", ] -[[package]] -name = "rusqlite" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" -dependencies = [ - "bitflags 2.9.4", - "fallible-iterator 0.3.0", - "fallible-streaming-iterator", - "hashlink 0.9.1", - "libsqlite3-sys", - "smallvec", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -11715,7 +9798,7 @@ dependencies = [ "borsh", "bytes", "num-traits", - "postgres-types 0.2.9", + "postgres-types", "rand 0.8.5", "rkyv", "serde", @@ -11765,7 +9848,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom 7.1.3", + "nom", ] [[package]] @@ -11791,7 +9874,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -11918,8 +10001,8 @@ dependencies = [ "rustls-webpki 0.103.13", "security-framework 3.6.0", "security-framework-sys", - "webpki-root-certs 1.0.7", - "windows-sys 0.61.2", + "webpki-root-certs", + "windows-sys 0.59.0", ] [[package]] @@ -11930,9 +10013,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-tokio-stream" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22557157d7395bc30727745b365d923f1ecc230c4c80b176545f3f4f08c46e33" +checksum = "faa7dc7c991d9164e55bbf1558029eb5b84d32cc4d61a7df5b8641b2deedc4b3" dependencies = [ "futures", "rustls 0.23.35", @@ -12036,28 +10119,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "rustyline" -version = "13.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "clipboard-win", - "fd-lock", - "home", - "libc", - "log", - "memchr", - "nix 0.27.1", - "radix_trie", - "unicode-segmentation", - "unicode-width 0.1.14", - "utf8parse", - "winapi", -] - [[package]] name = "ryu" version = "1.0.23" @@ -12081,25 +10142,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "saffron" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fb9a628596fc7590eb7edbf7b0613287be78df107f5f97b118aad59fb2eea9" -dependencies = [ - "chrono", - "nom 5.1.3", -] - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher 0.4.4", -] - [[package]] name = "samael" version = "0.0.20" @@ -12245,18 +10287,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scrypt" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" -dependencies = [ - "password-hash", - "pbkdf2", - "salsa20", - "sha2 0.10.9", -] - [[package]] name = "sct" version = "0.7.1" @@ -12289,7 +10319,6 @@ dependencies = [ "der", "generic-array", "pkcs8", - "serdect", "subtle", "zeroize", ] @@ -12368,9 +10397,9 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" -version = "1.0.220" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceecad4c782e936ac90ecfd6b56532322e3262b14320abf30ce89a92ffdbfe22" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -12409,30 +10438,20 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "serde_bytes" -version = "0.11.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" -dependencies = [ - "serde", - "serde_core", -] - [[package]] name = "serde_core" -version = "1.0.220" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddba47394f3b862d6ff6efdbd26ca4673e3566a307880a0ffb98f274bbe0ec32" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.220" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e1f3b1761e96def5ec6d04a6e7421c0404fa3cf5c0155f1e2848fae3d8cc08" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -12527,11 +10546,11 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.245.0" +version = "0.261.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945f93c91e0c7e4799b5fefff076756141aae92e262c4dc4833310dd3d2d845e" +checksum = "3495190857461e87a2716141043218aad5281f219f54a03b7ebbe605b3b931df" dependencies = [ - "deno_error", + "deno_error 0.6.1", "num-bigint", "serde", "smallvec", @@ -12599,16 +10618,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct", - "serde", -] - [[package]] name = "serial_test" version = "3.4.0" @@ -12670,27 +10679,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", -] - -[[package]] -name = "sha3" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" -dependencies = [ - "digest 0.10.7", - "keccak", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -12725,16 +10713,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -12767,36 +10745,12 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simd-abstraction" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" -dependencies = [ - "outref 0.1.0", -] - [[package]] name = "simd-adler32" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" -[[package]] -name = "simd-json" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2bcf6c6e164e81bc7a5d49fc6988b3d515d9e8c07457d7b74ffb9324b9cd40" -dependencies = [ - "getrandom 0.2.17", - "halfbrown", - "ref-cast", - "serde", - "serde_json", - "simdutf8", - "value-trait", -] - [[package]] name = "simdutf8" version = "0.1.5" @@ -12848,24 +10802,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" -[[package]] -name = "slotmap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" -dependencies = [ - "version_check", -] - -[[package]] -name = "sm3" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb9a3b702d0a7e33bc4d85a14456633d2b165c2ad839c5fd9a8417c1ab15860" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -12915,7 +10851,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -12929,32 +10865,13 @@ dependencies = [ "winapi", ] -[[package]] -name = "sourcemap" -version = "8.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" -dependencies = [ - "base64-simd 0.7.0", - "bitvec", - "data-encoding", - "debugid", - "if_chain", - "rustc-hash 1.1.0", - "rustc_version 0.2.3", - "serde", - "serde_json", - "unicode-id-start", - "url", -] - [[package]] name = "sourcemap" version = "9.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "314d62a489431668f719ada776ca1d49b924db951b7450f8974c9ae51ab05ad7" dependencies = [ - "base64-simd 0.8.0", + "base64-simd", "bitvec", "data-encoding", "debugid", @@ -12981,15 +10898,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" -dependencies = [ - "bitflags 2.9.4", -] - [[package]] name = "spki" version = "0.7.3" @@ -13007,17 +10915,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5851699c4033c63636f7ea4cf7b7c1f1bf06d0cc03cfb42e711de5a5c46cf326" dependencies = [ "base64 0.13.1", - "nom 7.1.3", + "nom", "serde", "unicode-segmentation", ] -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - [[package]] name = "sql-builder" version = "3.1.1" @@ -13093,7 +10995,7 @@ dependencies = [ "futures-io", "futures-util", "hashbrown 0.15.5", - "hashlink 0.10.0", + "hashlink", "indexmap 2.14.0", "log", "memchr", @@ -13175,7 +11077,7 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "itoa", "log", "md-5 0.10.6", @@ -13216,7 +11118,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "home", "itoa", "log", @@ -13292,7 +11194,7 @@ dependencies = [ "cfg-if", "libc", "psm", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -13303,11 +11205,10 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_enum" -version = "0.4.4" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" +checksum = "ae36a4951ca7bd1cfd991c241584a9824a70f6aff1e7d4f693fb3f2465e4030e" dependencies = [ - "proc-macro2", "quote", "swc_macros_common", "syn 2.0.117", @@ -13315,9 +11216,9 @@ dependencies = [ [[package]] name = "stringcase" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04028eeb851ed08af6aba5caa29f2d59a13ed168cee4d6bd753aeefcf1d636b0" +checksum = "72abeda133c49d7bddece6c154728f83eec8172380c80ab7096da9487e20d27c" [[package]] name = "stringprep" @@ -13423,64 +11324,48 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "swc_allocator" -version = "0.1.10" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76aa0eb65c0f39f9b6d82a7e5192c30f7ac9a78f084a21f270de1d8c600ca388" +checksum = "9d7eefd2c8b228a8c73056482b2ae4b3a1071fbe07638e3b55ceca8570cc48bb" dependencies = [ + "allocator-api2", "bumpalo", "hashbrown 0.14.5", - "ptr_meta", - "rustc-hash 1.1.0", - "triomphe", + "rustc-hash 2.1.2", ] [[package]] name = "swc_atoms" -version = "0.6.7" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" +checksum = "3500dcf04c84606b38464561edc5e46f5132201cb3e23cf9613ed4033d6b1bb2" dependencies = [ "hstr", "once_cell", - "rustc-hash 1.1.0", - "serde", -] - -[[package]] -name = "swc_cached" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83406221c501860fce9c27444f44125eafe9e598b8b81be7563d7036784cd05c" -dependencies = [ - "ahash 0.8.12", - "anyhow", - "dashmap 5.5.3", - "once_cell", - "regex", "serde", ] [[package]] name = "swc_common" -version = "0.37.5" +version = "14.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d0a8eaaf1606c9207077d75828008cb2dfb51b095a766bd2b72ef893576e31" +checksum = "c2bb772b3a26b8b71d4e8c112ced5b5867be2266364b58517407a270328a2696" dependencies = [ + "anyhow", "ast_node", "better_scoped_tls", - "cfg-if", + "bytes-str", "either", "from_variant", "new_debug_unreachable", "num-bigint", "once_cell", - "rustc-hash 1.1.0", + "rustc-hash 2.1.2", "serde", "siphasher 0.3.11", - "sourcemap 9.3.2", - "swc_allocator", "swc_atoms", "swc_eq_ignore_macros", + "swc_sourcemap", "swc_visit", "tracing", "unicode-width 0.1.14", @@ -13489,23 +11374,23 @@ dependencies = [ [[package]] name = "swc_config" -version = "0.1.15" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000" +checksum = "72e90b52ee734ded867104612218101722ad87ff4cf74fe30383bd244a533f97" dependencies = [ "anyhow", + "bytes-str", "indexmap 2.14.0", "serde", "serde_json", - "swc_cached", "swc_config_macro", ] [[package]] name = "swc_config_macro" -version = "0.1.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f56139042c1a95b54f5ca48baa0e0172d369bcc9d3d473dad1de36bae8399" +checksum = "7b416e8ce6de17dc5ea496e10c7012b35bbc0e3fef38d2e065eed936490db0b3" dependencies = [ "proc-macro2", "quote", @@ -13515,78 +11400,72 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.118.2" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f866d12e4d519052b92a0a86d1ac7ff17570da1272ca0c89b3d6f802cd79df" +checksum = "65c25af97d53cf8aab66a6c68f3418663313fc969ad267fc2a4d19402c329be1" dependencies = [ "bitflags 2.9.4", "is-macro", "num-bigint", + "once_cell", "phf 0.11.3", - "scoped-tls", + "rustc-hash 2.1.2", "serde", "string_enum", "swc_atoms", "swc_common", + "swc_visit", "unicode-id-start", ] [[package]] name = "swc_ecma_codegen" -version = "0.155.1" +version = "17.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7641608ef117cfbef9581a99d02059b522fcca75e5244fa0cbbd8606689c6f" +checksum = "bcf55c2d7555c93f4945e29f93b7529562be97ba16e60dd94c25724d746174ac" dependencies = [ + "ascii", + "compact_str", "memchr", "num-bigint", "once_cell", + "regex", + "rustc-hash 2.1.2", + "ryu-js", "serde", - "sourcemap 9.3.2", "swc_allocator", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_codegen_macros", + "swc_sourcemap", "tracing", ] [[package]] name = "swc_ecma_codegen_macros" -version = "0.7.7" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859fabde36db38634f3fad548dd5e3410c1aebba1b67a3c63e67018fa57a0bca" +checksum = "e276dc62c0a2625a560397827989c82a93fd545fcf6f7faec0935a82cc4ddbb8" dependencies = [ "proc-macro2", - "quote", "swc_macros_common", "syn 2.0.117", ] [[package]] -name = "swc_ecma_loader" -version = "0.49.1" +name = "swc_ecma_lexer" +version = "23.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55fa3d55045b97894bfb04d38aff6d6302ac8a6a38e3bb3dfb0d20475c4974a9" -dependencies = [ - "anyhow", - "pathdiff", - "serde", - "swc_atoms", - "swc_common", - "tracing", -] - -[[package]] -name = "swc_ecma_parser" -version = "0.149.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683dada14722714588b56481399c699378b35b2ba4deb5c4db2fb627a97fb54b" +checksum = "017d06ea85008234aa9fb34d805c7dc563f2ea6e03869ed5ac5a2dc27d561e4d" dependencies = [ + "arrayvec", + "bitflags 2.9.4", "either", - "new_debug_unreachable", "num-bigint", - "num-traits", "phf 0.11.3", + "rustc-hash 2.1.2", + "seq-macro", "serde", "smallvec", "smartstring", @@ -13595,23 +11474,52 @@ dependencies = [ "swc_common", "swc_ecma_ast", "tracing", - "typed-arena", +] + +[[package]] +name = "swc_ecma_loader" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c675d14700c92f12585049b22b02356f1e142f4b0c32a4d0eb4b7a968a4c0c1e" +dependencies = [ + "anyhow", + "pathdiff", + "rustc-hash 2.1.2", + "serde", + "swc_atoms", + "swc_common", + "tracing", +] + +[[package]] +name = "swc_ecma_parser" +version = "24.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9011783c975ba592ffc09cd208ced92b1dfabb2e5e0ef453559e2e25286127" +dependencies = [ + "either", + "num-bigint", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_lexer", + "tracing", ] [[package]] name = "swc_ecma_transforms_base" -version = "0.145.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f21494e75d0bd8ef42010b47cabab9caaed8f2207570e809f6f4eb51a710d1" +checksum = "6c6f1b8f4232e7a7f614ff7c0f6ccb89c2d028cdf7629f79ad710cff5b28b62c" dependencies = [ "better_scoped_tls", - "bitflags 2.9.4", "indexmap 2.14.0", "once_cell", + "par-core", "phf 0.11.3", - "rustc-hash 1.1.0", + "rustc-hash 2.1.2", "serde", - "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -13623,11 +11531,10 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.134.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3d884594385bea9405a2e1721151470d9a14d3ceec5dd773c0ca6894791601" +checksum = "108d4d52db6151f768a516fe86e6f21fc783b03fa2d20292999f29275fd0c71d" dependencies = [ - "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_transforms_base", @@ -13637,9 +11544,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_macros" -version = "0.5.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500a1dadad1e0e41e417d633b3d6d5de677c9e0d3159b94ba3348436cdb15aab" +checksum = "bc777288799bf6786e5200325a56e4fbabba590264a4a48a0c70b16ad0cf5cd8" dependencies = [ "proc-macro2", "quote", @@ -13649,56 +11556,54 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.179.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79938ff510fc647febd8c6c3ef4143d099fdad87a223680e632623d056dae2dd" +checksum = "39b3b34f6a28348416174912009d09994ab71c867682ec78d641a9feb3a96b4e" dependencies = [ "either", - "rustc-hash 1.1.0", + "rustc-hash 2.1.2", "serde", - "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_classes", - "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", ] [[package]] name = "swc_ecma_transforms_react" -version = "0.191.0" +version = "30.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c76d8b9792ce51401d38da0fa62158d61f6d80d16d68fe5b03ce4bf5fba383" +checksum = "69ea0052ac23b5b9fbc85bbdb1791b36b918f9d55f594b0ed8e25babb4c32d16" dependencies = [ - "base64 0.21.7", - "dashmap 5.5.3", + "base64 0.22.1", + "bytes-str", "indexmap 2.14.0", "once_cell", + "rustc-hash 2.1.2", "serde", "sha1", "string_enum", - "swc_allocator", "swc_atoms", "swc_common", "swc_config", "swc_ecma_ast", "swc_ecma_parser", "swc_ecma_transforms_base", - "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", ] [[package]] name = "swc_ecma_transforms_typescript" -version = "0.198.1" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15455da4768f97186c40523e83600495210c11825d3a44db43383fd81eace88d" +checksum = "3872c006ccfdcc19f1cf5c01c15915a69964ba7982c9f581cdb7e727e77b9a2c" dependencies = [ - "ryu-js", + "bytes-str", + "rustc-hash 2.1.2", "serde", "swc_atoms", "swc_common", @@ -13711,28 +11616,28 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.134.2" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029eec7dd485923a75b5a45befd04510288870250270292fc2c1b3a9e7547408" +checksum = "83259addd99ed4022aa9fc4d39428c008d3d42533769e1a005529da18cde4568" dependencies = [ "indexmap 2.14.0", "num_cpus", "once_cell", - "rustc-hash 1.1.0", + "par-core", + "rustc-hash 2.1.2", "ryu-js", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_visit", "tracing", - "unicode-id", ] [[package]] name = "swc_ecma_visit" -version = "0.104.8" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1c6802e68e51f336e8bc9644e9ff9da75d7da9c1a6247d532f2e908aa33e81" +checksum = "75a579aa8f9e212af521588df720ccead079c09fe5c8f61007cf724324aed3a0" dependencies = [ "new_debug_unreachable", "num-bigint", @@ -13745,9 +11650,9 @@ dependencies = [ [[package]] name = "swc_eq_ignore_macros" -version = "0.1.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" +checksum = "c16ce73424a6316e95e09065ba6a207eba7765496fed113702278b7711d4b632" dependencies = [ "proc-macro2", "quote", @@ -13756,38 +11661,44 @@ dependencies = [ [[package]] name = "swc_macros_common" -version = "0.3.13" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" +checksum = "aae1efbaa74943dc5ad2a2fb16cbd78b77d7e4d63188f3c5b4df2b4dcd2faaae" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] +[[package]] +name = "swc_sourcemap" +version = "9.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de08ef00f816acdd1a58ee8a81c0e1a59eefef2093aefe5611f256fa6b64c4d7" +dependencies = [ + "base64-simd", + "bitvec", + "bytes-str", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash 2.1.2", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + [[package]] name = "swc_visit" -version = "0.6.2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ceb044142ba2719ef9eb3b6b454fce61ab849eb696c34d190f04651955c613d" +checksum = "62fb71484b486c185e34d2172f0eabe7f4722742aad700f426a494bb2de232a2" dependencies = [ "either", "new_debug_unreachable", ] -[[package]] -name = "swc_visit_macros" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "swc_macros_common", - "syn 2.0.117", -] - [[package]] name = "symlink" version = "0.1.0" @@ -13825,18 +11736,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.2" @@ -13859,12 +11758,22 @@ dependencies = [ [[package]] name = "sys_traits" -version = "0.1.7" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b46ac05dfbe9fd3a9703eff20e17f5b31e7b6a54daf27a421dcd56c7a27ecdd" +checksum = "dc4707edf3196e8037ee45018d1bb1bfb233b0e4fc440fa3d3f25bc69bfdaf26" dependencies = [ - "libc", - "windows-sys 0.59.0", + "sys_traits_macros", +] + +[[package]] +name = "sys_traits_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181f22127402abcf8ee5c83ccd5b408933fec36a6095cf82cda545634692657e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -13925,7 +11834,7 @@ dependencies = [ "bytesize", "lazy_static", "libc", - "nom 7.1.3", + "nom", "time", "winapi", ] @@ -13962,7 +11871,7 @@ dependencies = [ "lru 0.16.4", "lz4_flex 0.13.0", "measure_time", - "memmap2 0.9.10", + "memmap2", "once_cell", "oneshot", "rayon", @@ -14040,7 +11949,7 @@ version = "0.25.0" source = "git+https://github.com/windmill-labs/tantivy?rev=6ae7c70bc603b8e69e27f3240e08bd00a93fb12c#6ae7c70bc603b8e69e27f3240e08bd00a93fb12c" dependencies = [ "fnv", - "nom 7.1.3", + "nom", "ordered-float 5.3.0", "serde", "serde_json", @@ -14093,6 +12002,15 @@ dependencies = [ "xattr", ] +[[package]] +name = "temp_deno_which" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366c5ccd670145885feb6efd6bbf2478ed236c4c3839046fcc8e2a1a84c51091" +dependencies = [ + "either", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -14103,7 +12021,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -14122,7 +12040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -14399,7 +12317,7 @@ dependencies = [ "bytes", "io-uring", "libc", - "mio 1.2.0", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -14410,16 +12328,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "tokio-eld" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9166030f05d6bc5642bdb8f8c2be31eb3c02cd465d662bcdc2df82d4aa41a584" -dependencies = [ - "hdrhistogram", - "tokio", -] - [[package]] name = "tokio-graceful" version = "0.1.6" @@ -14444,18 +12352,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "tokio-metrics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eace09241d62c98b7eeb1107d4c5c64ca3bd7da92e8c218c153ab3a78f9be112" -dependencies = [ - "futures-util", - "pin-project-lite", - "tokio", - "tokio-stream", -] - [[package]] name = "tokio-native-tls" version = "0.3.1" @@ -14468,50 +12364,24 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.11" -source = "git+https://github.com/imor/rust-postgres?rev=20265ef38e32a06f76b6f9b678e2077fc2211f6b#20265ef38e32a06f76b6f9b678e2077fc2211f6b" +version = "0.7.15" +source = "git+https://github.com/MaterializeInc/rust-postgres?rev=78c1222577bb091d69bc22b1bc7ad01c14675abe#78c1222577bb091d69bc22b1bc7ad01c14675abe" dependencies = [ "async-trait", "byteorder", "bytes", - "fallible-iterator 0.2.0", + "fallible-iterator", "futures-channel", "futures-util", "log", "parking_lot", "percent-encoding", - "phf 0.11.3", + "phf 0.13.1", "pin-project-lite", - "postgres-protocol 0.6.7", - "postgres-types 0.2.7", - "rand 0.8.5", - "socket2 0.5.10", - "tokio", - "tokio-util", - "whoami", -] - -[[package]] -name = "tokio-postgres" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c95d533c83082bb6490e0189acaa0bbeef9084e60471b696ca6988cd0541fb0" -dependencies = [ - "async-trait", - "byteorder", - "bytes", - "fallible-iterator 0.2.0", - "futures-channel", - "futures-util", - "log", - "parking_lot", - "percent-encoding", - "phf 0.11.3", - "pin-project-lite", - "postgres-protocol 0.6.11", - "postgres-types 0.2.9", + "postgres-protocol", + "postgres-types", "rand 0.9.0", - "socket2 0.5.10", + "socket2 0.6.3", "tokio", "tokio-util", "whoami", @@ -14624,12 +12494,24 @@ dependencies = [ "futures-io", "futures-sink", "futures-util", - "hashbrown 0.15.5", "pin-project-lite", "slab", "tokio", ] +[[package]] +name = "tokio-vsock" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b319ef9394889dab2e1b4f0085b45ba11d0c79dc9d1a9d1afc057d009d0f1c7" +dependencies = [ + "bytes", + "futures", + "libc", + "tokio", + "vsock", +] + [[package]] name = "tokio-websockets" version = "0.10.1" @@ -15114,29 +12996,12 @@ dependencies = [ "utf-8", ] -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "rand 0.8.5", - "static_assertions", -] - [[package]] name = "twox-hash" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - [[package]] name = "typed-path" version = "0.12.3" @@ -15272,12 +13137,6 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" -[[package]] -name = "unicode-id" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580" - [[package]] name = "unicode-id-start" version = "1.4.0" @@ -15378,7 +13237,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common 0.1.7", + "crypto-common", "subtle", ] @@ -15501,54 +13360,26 @@ dependencies = [ [[package]] name = "v8" -version = "130.0.7" +version = "137.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a511192602f7b435b0a241c1947aa743eb7717f20a9195f4b5e8ed1952e01db1" +checksum = "33995a1fee055ff743281cde33a41f0d618ee0bdbe8bdf6859e11864499c2595" dependencies = [ - "bindgen 0.70.1", + "bindgen 0.71.1", "bitflags 2.9.4", "fslock", "gzip-header", "home", - "miniz_oxide 0.7.4", - "once_cell", + "miniz_oxide", "paste", "which 6.0.3", ] -[[package]] -name = "v8_valueserializer" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97599c400fc79925922b58303e98fcb8fa88f573379a08ddb652e72cbd2e70f6" -dependencies = [ - "bitflags 2.9.4", - "encoding_rs", - "indexmap 2.14.0", - "num-bigint", - "serde", - "thiserror 1.0.69", - "wtf8", -] - [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "value-trait" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9170e001f458781e92711d2ad666110f153e4e50bfd5cbd02db6547625714187" -dependencies = [ - "float-cmp", - "halfbrown", - "itoa", - "ryu", -] - [[package]] name = "vcpkg" version = "0.2.15" @@ -15567,6 +13398,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" +[[package]] +name = "vsock" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba782755fc073877e567c2253c0be48e4aa9a254c232d36d3985dfae0bd5205" +dependencies = [ + "libc", + "nix 0.31.3", +] + [[package]] name = "vte" version = "0.14.1" @@ -15765,11 +13606,11 @@ dependencies = [ [[package]] name = "wasm_dep_analyzer" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca" +checksum = "e51cf5f08b357e64cd7642ab4bbeb11aecab9e15520692129624fb9908b8df2c" dependencies = [ - "deno_error", + "deno_error 0.6.1", "thiserror 2.0.18", ] @@ -15820,12 +13661,15 @@ dependencies = [ ] [[package]] -name = "webpki-root-certs" -version = "0.26.11" +name = "web-transport-proto" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +checksum = "974fa1e325e6cc5327de8887f189a441fcff4f8eedcd31ec87f0ef0cc5283fbc" dependencies = [ - "webpki-root-certs 1.0.7", + "bytes", + "http 1.4.0", + "thiserror 2.0.18", + "url", ] [[package]] @@ -15855,89 +13699,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "wgpu-core" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" -dependencies = [ - "arrayvec", - "bit-vec 0.6.3", - "bitflags 2.9.4", - "cfg_aliases 0.1.1", - "codespan-reporting", - "document-features", - "indexmap 2.14.0", - "log", - "naga", - "once_cell", - "parking_lot", - "profiling", - "raw-window-handle", - "ron", - "rustc-hash 1.1.0", - "serde", - "smallvec", - "thiserror 1.0.69", - "web-sys", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-hal" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172e490a87295564f3fcc0f165798d87386f6231b04d4548bca458cbbfd63222" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bit-set 0.5.3", - "bitflags 2.9.4", - "block", - "cfg_aliases 0.1.1", - "core-graphics-types", - "d3d12", - "glow", - "glutin_wgl_sys", - "gpu-alloc", - "gpu-descriptor", - "js-sys", - "khronos-egl", - "libc", - "libloading 0.8.9", - "log", - "metal", - "naga", - "ndk-sys", - "objc", - "once_cell", - "parking_lot", - "profiling", - "range-alloc", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 1.0.69", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "winapi", -] - -[[package]] -name = "wgpu-types" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" -dependencies = [ - "bitflags 2.9.4", - "js-sys", - "serde", - "web-sys", -] - [[package]] name = "which" version = "4.4.2" @@ -16001,7 +13762,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -16114,13 +13875,19 @@ dependencies = [ "aws-sdk-bedrockruntime", "aws-smithy-types", "base64 0.22.1", + "bytes", + "eventsource-stream", + "futures", "lazy_static", + "mime_guess", "reqwest 0.13.1", "serde", "serde_json", "sqlx", "tokio", + "tokio-stream", "tracing", + "ulid", "uuid", "windmill-common", "windmill-mcp", @@ -16168,7 +13935,7 @@ dependencies = [ "const_format", "cookie", "cron", - "dashmap 6.1.0", + "dashmap", "datafusion", "ed25519-dalek", "eventsource-stream", @@ -16176,7 +13943,7 @@ dependencies = [ "futures", "git-version", "hex", - "hmac 0.12.1", + "hmac", "http 1.4.0", "hyper 1.9.0", "indexmap 2.14.0", @@ -16192,7 +13959,7 @@ dependencies = [ "openidconnect", "openssl", "pin-project", - "postgres-native-tls 0.5.1", + "postgres-native-tls 0.5.3", "prometheus", "quick_cache", "rand 0.9.0", @@ -16215,7 +13982,7 @@ dependencies = [ "time", "tokio", "tokio-native-tls", - "tokio-postgres 0.7.13", + "tokio-postgres", "tokio-stream", "tokio-util", "tower 0.5.3", @@ -16684,7 +14451,7 @@ dependencies = [ "argon2", "axum 0.8.4", "chrono", - "dashmap 6.1.0", + "dashmap", "http 1.4.0", "hyper 1.9.0", "lazy_static", @@ -16810,7 +14577,7 @@ dependencies = [ "crc", "cron", "croner", - "dashmap 6.1.0", + "dashmap", "datafusion", "equivalent", "futures", @@ -16819,7 +14586,7 @@ dependencies = [ "git-version", "globset", "hex", - "hmac 0.12.1", + "hmac", "hyper 1.9.0", "indexmap 2.14.0", "itertools 0.14.0", @@ -16838,7 +14605,7 @@ dependencies = [ "pep440_rs", "phf 0.11.3", "pin-project-lite", - "postgres-native-tls 0.5.1", + "postgres-native-tls 0.5.3", "prometheus", "quick_cache", "rand 0.9.0", @@ -16864,7 +14631,7 @@ dependencies = [ "thiserror 2.0.18", "tikv-jemalloc-ctl", "tokio", - "tokio-postgres 0.7.13", + "tokio-postgres", "tokio-stream", "tokio-util", "tonic 0.13.1", @@ -17005,7 +14772,7 @@ dependencies = [ "backon", "base64 0.22.1", "chrono", - "hmac 0.12.1", + "hmac", "http 1.4.0", "itertools 0.14.0", "lazy_static", @@ -17037,7 +14804,7 @@ dependencies = [ "base64 0.22.1", "chrono", "hex", - "hmac 0.12.1", + "hmac", "itertools 0.14.0", "lazy_static", "reqwest 0.12.28", @@ -17379,11 +15146,11 @@ dependencies = [ "chrono", "chrono-tz", "cron", - "dashmap 6.1.0", + "dashmap", "futures", "futures-core", "hex", - "hmac 0.12.1", + "hmac", "itertools 0.14.0", "lazy_static", "once_cell", @@ -17414,12 +15181,12 @@ dependencies = [ "deno_ast", "deno_console", "deno_core", - "deno_error", + "deno_error 0.6.1", "deno_fetch", + "deno_fs", "deno_io", "deno_net", "deno_permissions", - "deno_runtime", "deno_telemetry", "deno_tls", "deno_url", @@ -17640,7 +15407,7 @@ dependencies = [ "constant_time_eq 0.3.1", "futures", "hex", - "hmac 0.12.1", + "hmac", "http 1.4.0", "hyper 1.9.0", "itertools 0.14.0", @@ -17750,7 +15517,7 @@ dependencies = [ "lazy_static", "native-tls", "pg_escape", - "postgres-native-tls 0.5.0", + "postgres-native-tls 0.5.2", "quick_cache", "rand 0.9.0", "rust_decimal", @@ -17759,7 +15526,7 @@ dependencies = [ "sqlx", "thiserror 2.0.18", "tokio", - "tokio-postgres 0.7.11", + "tokio-postgres", "tokio-stream", "tracing", "uuid", @@ -17870,7 +15637,7 @@ dependencies = [ "gcp_auth", "git-version", "hex", - "hmac 0.12.1", + "hmac", "hudsucker", "hyper-http-proxy", "hyper-tls", @@ -17879,7 +15646,7 @@ dependencies = [ "jsonwebtoken 8.3.0", "lazy_static", "libffi-sys", - "libloading 0.8.9", + "libloading", "mappable-rc", "mime_guess", "mysql_async", @@ -17891,7 +15658,7 @@ dependencies = [ "oracle", "pem 3.0.6", "pep440_rs", - "postgres-native-tls 0.5.1", + "postgres-native-tls 0.5.3", "process-wrap", "prometheus", "prost", @@ -17910,7 +15677,7 @@ dependencies = [ "tempfile", "tiberius", "tokio", - "tokio-postgres 0.7.13", + "tokio-postgres", "tokio-stream", "tokio-util", "tracing", @@ -17949,7 +15716,7 @@ dependencies = [ "windmill-types", "windmill-worker-volumes", "windows 0.61.3", - "x509-parser 0.16.0", + "x509-parser", "yaml-rust", ] @@ -18050,19 +15817,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" @@ -18665,12 +16419,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" -[[package]] -name = "wtf8" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01ae8492c38f52376efd3a17d0994b6bcf3df1e39c0226d458b7d81670b2a06" - [[package]] name = "wyz" version = "0.5.1" @@ -18680,47 +16428,18 @@ dependencies = [ "tap", ] -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", - "serde", - "zeroize", -] - -[[package]] -name = "x509-parser" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" -dependencies = [ - "asn1-rs 0.5.2", - "data-encoding", - "der-parser 8.2.0", - "lazy_static", - "nom 7.1.3", - "oid-registry 0.6.1", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] - [[package]] name = "x509-parser" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ - "asn1-rs 0.6.2", + "asn1-rs", "data-encoding", - "der-parser 9.0.0", + "der-parser", "lazy_static", - "nom 7.1.3", - "oid-registry 0.7.1", + "nom", + "oid-registry", "ring 0.17.14", "rusticata-macros", "thiserror 1.0.69", @@ -18737,12 +16456,6 @@ dependencies = [ "rustix 1.1.4", ] -[[package]] -name = "xml-rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" - [[package]] name = "xmlparser" version = "0.13.6" @@ -18782,18 +16495,6 @@ dependencies = [ "time", ] -[[package]] -name = "yoke" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive 0.7.5", - "zerofrom", -] - [[package]] name = "yoke" version = "0.8.2" @@ -18801,22 +16502,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", - "yoke-derive 0.8.2", + "yoke-derive", "zerofrom", ] -[[package]] -name = "yoke-derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", - "synstructure 0.13.2", -] - [[package]] name = "yoke-derive" version = "0.8.2" @@ -18826,7 +16515,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "synstructure 0.13.2", + "synstructure", ] [[package]] @@ -18867,7 +16556,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", - "synstructure 0.13.2", + "synstructure", ] [[package]] @@ -18875,20 +16564,6 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] [[package]] name = "zerotrie" @@ -18897,7 +16572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", - "yoke 0.8.2", + "yoke", "zerofrom", ] @@ -18907,7 +16582,7 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ - "yoke 0.8.2", + "yoke", "zerofrom", "zerovec-derive", ] diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 042179683d..326b777385 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -207,6 +207,36 @@ all_sqlx_features = ["all_languages", "enterprise", "enterprise_saml", "embeddin object_store = { git = "https://github.com/apache/arrow-rs-object-store", rev = "36752c975d4f29e20b57c91f81a10872dcd48ae7" } # Use tiberius main branch for libgssapi 0.8.1 fix (https://github.com/prisma/tiberius/issues/343) tiberius = { git = "https://github.com/prisma/tiberius", rev = "59db57960a14b422fb3a1309aa4aa47880896ff8" } +# Pin tokio-postgres / postgres-types / postgres-protocol to the +# MaterializeInc fork. windmill-trigger-postgres already pulled this +# fork in transitively for the postgres-replication crate +# (CopyBothDuplex, LogicalReplicationStream, TupleData with binary +# tuple support) which upstream rust-postgres has declined to merge +# since 2021 (PR #752 → #778, both still unmerged). +# +# MI also carries a mitigation for the +# Client::query_typed_raw / Client::prepare deadlock on result columns +# whose Oid the client doesn't know about yet (citext, custom enums / +# domains, postgis): MI's 2025-12-11 PR #33 resized the per-request +# response channel from mpsc::channel(1) → mpsc::channel(1024). +# bounded(1024) is sufficient for any realistic typeinfo deferral +# (need ~2-3 batches) but leaves a theoretical failure mode at +# >~64 MB results with a custom-Oid column. The strict-correct fix is +# mpsc::unbounded(); a follow-up PR to MI is open proposing that. +# +# The [patch.crates-io] entries below force windmill-worker's +# pg_executor (which imports `tokio_postgres::` directly from +# crates.io) onto the same fork as windmill-trigger-postgres, so the +# deadlock mitigation reaches both consumers. +# +# Upstream deadlock PRs (open, not on the critical path now that MI +# is mitigated): +# https://github.com/rust-postgres/rust-postgres/pull/1348 +# https://github.com/rust-postgres/rust-postgres/pull/1349 +# Reproducer: https://github.com/rubenfiszel/tokio-postgres-deadlock-repro +tokio-postgres = { git = "https://github.com/MaterializeInc/rust-postgres", rev = "78c1222577bb091d69bc22b1bc7ad01c14675abe" } +postgres-types = { git = "https://github.com/MaterializeInc/rust-postgres", rev = "78c1222577bb091d69bc22b1bc7ad01c14675abe" } +postgres-protocol = { git = "https://github.com/MaterializeInc/rust-postgres", rev = "78c1222577bb091d69bc22b1bc7ad01c14675abe" } [dependencies] anyhow.workspace = true @@ -387,8 +417,7 @@ tokio-stream = { version = "0.1.17" } tower = "^0" tower-http = { version = "^0.6", features = ["trace", "cors", "catch-panic"] } tower-cookies = "^0.11" -#stuck because of swc for now -serde = "=1.0.220" +serde = "^1" serde_json = { version = "^1", features = ["preserve_order", "raw_value"] } serde_yml = "0.0.12" uuid = { version = "^1", features = ["serde", "v4", "js"] } @@ -443,21 +472,29 @@ aws-sdk-rds = "^1" async-trait = "0.1.88" -v8 = "=130.0.7" # Exact version NOTE: Do not forget to update version and hash in flake.nix -deno_fetch = "0.214.0" -deno_tls = "0.177.0" -deno_console = "0.190.0" -deno_url = "0.190.0" -deno_webidl = "0.190.0" -deno_web = "0.221.0" -deno_io = "0.100.0" -deno_net = "0.182.0" -deno_core = "0.336.0" -deno_ast = { version = "=0.44.0", features = ["transpiling"] } -deno_permissions = "0.49.0" -deno_runtime = { version = "0.198.0", features = ["transpile"] } -deno_telemetry = "0.12.0" -deno_error = "=0.5.5" +v8 = "=137.1.0" # Exact version NOTE: Do not forget to update version and hash in flake.nix +# deno_* pin set: deno v2.4.0 base, with deno_ast force-overridden to =0.51.0. +# Rationale: deno_ast 0.51.0 is the first version pulling swc_common =14.0.4, +# the first swc_common patch that dropped `pub use serde::__private as serde;` +# (the line that capped our workspace serde pin at =1.0.220). v2.4.0's other +# pins keep deno_tls at 0.196.0 which uses permissive `rustls ^0.23.11`, +# compatible with aws-sdk-bedrockruntime's `^0.23.31` requirement. deno_tls +# 0.198+ tightened that to exact `=0.23.28`, which would have made any +# meaningful deno bump resolver-impossible against aws-sdk. +deno_fetch = "0.233.0" +deno_tls = "0.196.0" +deno_console = "0.209.0" +deno_url = "0.209.0" +deno_webidl = "0.209.0" +deno_web = "0.240.0" +deno_io = "0.119.0" +deno_fs = "0.119.0" +deno_net = "0.201.0" +deno_core = "0.352.0" +deno_ast = { version = "=0.51.0", features = ["transpiling"] } +deno_permissions = "0.68.0" +deno_telemetry = "0.31.0" +deno_error = "=0.6.1" rustls-pemfile = "2.2.0" # only used with special deno_core_mac feature to prevent ffi issue on macos, requires libffi to be installed @@ -470,10 +507,10 @@ google-cloud-googleapis = {version = "0.16.1", features = ["pubsub"]} winapi = { version = "0.3.9", features = ["sysinfoapi"] } sysinfo = { version = "0.32.1" } -swc_common = "=0.37.5" -swc_ecma_parser = "=0.149.1" -swc_ecma_ast = "=0.118.2" -swc_ecma_visit = "=0.104.8" +swc_common = "=14.0.4" +swc_ecma_parser = "=24.0.3" +swc_ecma_ast = "=15.0.0" +swc_ecma_visit = "=15.0.0" async-recursion = "^1" @@ -517,8 +554,8 @@ wasm-bindgen-test = "^0" convert_case = "0.6.0" getrandom = "0.2" tokio-postgres = {version = "^0.7", features = ["array-impls", "with-serde_json-1", "with-chrono-0_4", "with-uuid-1", "with-bit-vec-0_6"]} -rust-postgres = { package = "tokio-postgres", git = "https://github.com/imor/rust-postgres", rev = "20265ef38e32a06f76b6f9b678e2077fc2211f6b"} -rust-postgres-native-tls = { package = "postgres-native-tls", git = "https://github.com/imor/rust-postgres", features = ["runtime"], rev = "20265ef38e32a06f76b6f9b678e2077fc2211f6b" } +rust-postgres = { package = "tokio-postgres", git = "https://github.com/MaterializeInc/rust-postgres", rev = "78c1222577bb091d69bc22b1bc7ad01c14675abe"} +rust-postgres-native-tls = { package = "postgres-native-tls", git = "https://github.com/MaterializeInc/rust-postgres", features = ["runtime"], rev = "78c1222577bb091d69bc22b1bc7ad01c14675abe" } bit-vec = "=0.6.3" mappable-rc = "^0" mysql_async = { version = "*", default-features = false, features = ["minimal", "default", "native-tls-tls", "rust_decimal"]} diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 401a8213f7..91d8581950 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -c8d100d74b8de6bd26fc973d5edbd8853d54dd8b +c6cd1afe2d9e04809b30751cd1687b28a65e62b1 diff --git a/backend/migrations/20260511075225_add_assets_to_operator_settings.down.sql b/backend/migrations/20260511075225_add_assets_to_operator_settings.down.sql new file mode 100644 index 0000000000..c38c2a1e42 --- /dev/null +++ b/backend/migrations/20260511075225_add_assets_to_operator_settings.down.sql @@ -0,0 +1,19 @@ +-- Remove "assets" key from operator_settings +UPDATE workspace_settings +SET operator_settings = operator_settings - 'assets' +WHERE operator_settings IS NOT NULL + AND operator_settings ? 'assets'; + +-- Revert the column default +ALTER TABLE workspace_settings +ALTER COLUMN operator_settings SET DEFAULT '{ + "runs": true, + "groups": true, + "folders": true, + "workers": true, + "triggers": true, + "resources": true, + "schedules": true, + "variables": true, + "audit_logs": true +}'; diff --git a/backend/migrations/20260511075225_add_assets_to_operator_settings.up.sql b/backend/migrations/20260511075225_add_assets_to_operator_settings.up.sql new file mode 100644 index 0000000000..96aba860ec --- /dev/null +++ b/backend/migrations/20260511075225_add_assets_to_operator_settings.up.sql @@ -0,0 +1,21 @@ +-- Add "assets": true to operator_settings for all workspaces that have operator_settings +-- but don't already have an "assets" key +UPDATE workspace_settings +SET operator_settings = operator_settings || '{"assets": true}'::jsonb +WHERE operator_settings IS NOT NULL + AND NOT operator_settings ? 'assets'; + +-- Update the column default to include assets +ALTER TABLE workspace_settings +ALTER COLUMN operator_settings SET DEFAULT '{ + "runs": true, + "groups": true, + "folders": true, + "workers": true, + "triggers": true, + "resources": true, + "schedules": true, + "variables": true, + "audit_logs": true, + "assets": true +}'; diff --git a/backend/parsers/windmill-parser-ts-asset/src/lib.rs b/backend/parsers/windmill-parser-ts-asset/src/lib.rs index 72e99437b5..5138d8669e 100644 --- a/backend/parsers/windmill-parser-ts-asset/src/lib.rs +++ b/backend/parsers/windmill-parser-ts-asset/src/lib.rs @@ -12,7 +12,7 @@ use AssetUsageAccessType::*; pub fn parse_assets(code: &str) -> anyhow::Result { let cm: Lrc = Default::default(); - let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.into()); + let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.to_string()); let lexer = Lexer::new( // We want to parse ecmascript Syntax::Typescript(TsSyntax::default()), diff --git a/backend/parsers/windmill-parser-ts/src/lib.rs b/backend/parsers/windmill-parser-ts/src/lib.rs index 1ae22879b6..1e78ec8665 100644 --- a/backend/parsers/windmill-parser-ts/src/lib.rs +++ b/backend/parsers/windmill-parser-ts/src/lib.rs @@ -129,7 +129,7 @@ impl Visit for ImportsFinder { /// See also: [`parse_relative_imports`] for resolved absolute paths. pub fn parse_expr_for_imports(code: &str, skip_type_only: bool) -> anyhow::Result> { let cm: Lrc = Default::default(); - let fm = cm.new_source_file(FileName::Custom("main.d.ts".into()).into(), code.into()); + let fm = cm.new_source_file(FileName::Custom("main.d.ts".into()).into(), code.to_string()); let mut tss = TsSyntax::default(); tss.disallow_ambiguous_jsx_like; tss.tsx = true; @@ -263,7 +263,7 @@ impl Visit for OutputFinder { pub fn parse_expr_for_ids(code: &str) -> anyhow::Result> { let cm: Lrc = Default::default(); - let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.into()); + let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.to_string()); let lexer = Lexer::new( // We want to parse ecmascript Syntax::Es(EsSyntax { jsx: false, ..Default::default() }), @@ -305,7 +305,7 @@ pub fn parse_deno_signature( entrypoint_override: Option, ) -> anyhow::Result { let cm: Lrc = Default::default(); - let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.into()); + let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.to_string()); let lexer = Lexer::new( // We want to parse ecmascript Syntax::Typescript(TsSyntax::default()), diff --git a/backend/parsers/windmill-parser-wac/src/typescript.rs b/backend/parsers/windmill-parser-wac/src/typescript.rs index 87fa7cef01..9ad84a2e97 100644 --- a/backend/parsers/windmill-parser-wac/src/typescript.rs +++ b/backend/parsers/windmill-parser-wac/src/typescript.rs @@ -712,7 +712,7 @@ fn extract_ts_params(params: &[swc_ecma_ast::Param], cm: &Lrc) -> Vec pub fn parse_ts_workflow(code: &str) -> Result> { let cm: Lrc = Default::default(); - let fm = cm.new_source_file(FileName::Custom("workflow.ts".into()).into(), code.into()); + let fm = cm.new_source_file(FileName::Custom("workflow.ts".into()).into(), code.to_string()); let lexer = Lexer::new( Syntax::Typescript(TsSyntax::default()), Default::default(), diff --git a/backend/src/ee_oss.rs b/backend/src/ee_oss.rs index 2aefaf7431..4dcaf2437b 100644 --- a/backend/src/ee_oss.rs +++ b/backend/src/ee_oss.rs @@ -8,6 +8,6 @@ pub async fn set_license_key(_license_key: String, _db: Option<&windmill_common: } #[cfg(all(feature = "enterprise", not(feature = "private")))] -pub async fn verify_license_key() -> () { +pub async fn verify_license_key(_db: Option<&windmill_common::db::DB>) -> () { // Implementation is not open source } diff --git a/backend/src/main.rs b/backend/src/main.rs index 3049064624..9a2709e9a9 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1441,7 +1441,7 @@ Windmill Community Edition {GIT_VERSION} tracing::error!("Failed to reload license key on agent: {e:#}"); } #[cfg(feature = "enterprise")] - ee_oss::verify_license_key().await; + ee_oss::verify_license_key(conn.as_sql()).await; } // update min version explicitly. diff --git a/backend/src/monitor.rs b/backend/src/monitor.rs index 59a2f47ed0..0ddc02b256 100644 --- a/backend/src/monitor.rs +++ b/backend/src/monitor.rs @@ -2373,7 +2373,19 @@ pub async fn monitor_db( let verify_license_key_f = async { #[cfg(feature = "enterprise")] if !initial_load { - verify_license_key().await; + verify_license_key(conn.as_sql()).await; + } + }; + + let enforce_offline_caps_f = async { + #[cfg(feature = "enterprise")] + if server_mode && !initial_load { + if let Some(db) = conn.as_sql() { + // Cheap: one query for workers active in the last 2 minutes. + if let Err(e) = windmill_common::ee_oss::enforce_offline_caps(db).await { + tracing::error!("Failed to enforce offline license caps: {e:#}"); + } + } } }; @@ -2522,6 +2534,7 @@ pub async fn monitor_db( vacuum_queue_f, expose_queue_metrics_f, verify_license_key_f, + enforce_offline_caps_f, worker_groups_alerts_f, jobs_waiting_alerts_f, low_disk_alerts_f, @@ -2853,6 +2866,11 @@ pub async fn reload_base_url_setting(conn: &Connection) -> error::Result<()> { IS_SECURE.store(is_secure, Ordering::Relaxed); + #[cfg(feature = "enterprise")] + { + crate::ee_oss::verify_license_key(conn.as_sql()).await; + } + Ok(()) } diff --git a/backend/windmill-ai/Cargo.toml b/backend/windmill-ai/Cargo.toml index 69cc0f181b..542c390cc0 100644 --- a/backend/windmill-ai/Cargo.toml +++ b/backend/windmill-ai/Cargo.toml @@ -21,6 +21,10 @@ windmill-mcp = { workspace = true, optional = true } async-trait.workspace = true base64.workspace = true +bytes.workspace = true +eventsource-stream.workspace = true +futures.workspace = true +mime_guess.workspace = true reqwest.workspace = true serde.workspace = true serde_json.workspace = true @@ -29,6 +33,8 @@ uuid.workspace = true lazy_static.workspace = true tracing.workspace = true tokio.workspace = true +tokio-stream.workspace = true +ulid.workspace = true # Bedrock (optional) aws-config = { workspace = true, optional = true } diff --git a/backend/windmill-worker/src/ai/image_handler.rs b/backend/windmill-ai/src/image_handler.rs similarity index 86% rename from backend/windmill-worker/src/ai/image_handler.rs rename to backend/windmill-ai/src/image_handler.rs index 4fc0bcb4db..5bd9794da5 100644 --- a/backend/windmill-worker/src/ai/image_handler.rs +++ b/backend/windmill-ai/src/image_handler.rs @@ -1,16 +1,18 @@ +use crate::types::*; use base64::Engine; use futures; use ulid; +use uuid::Uuid; use windmill_common::{client::AuthedClient, error::Error}; -use windmill_queue::MiniPulledJob; use windmill_types::s3::S3Object; -use crate::ai::types::*; - -/// Upload image to S3 and return S3Object +/// Upload image to S3 and return S3Object. +/// +/// The caller must provide an AuthedClient authorized for `workspace_id`. pub async fn upload_image_to_s3( base64_image: &str, - job: &MiniPulledJob, + workspace_id: &str, + job_id: &Uuid, client: &AuthedClient, ) -> Result { let image_bytes = base64::engine::general_purpose::STANDARD @@ -19,7 +21,7 @@ pub async fn upload_image_to_s3( // Generate unique S3 key let unique_id = ulid::Ulid::new().to_string(); - let s3_key = format!("ai_images/{}/{}.png", job.id, unique_id); + let s3_key = format!("ai_images/{}/{}.png", job_id, unique_id); // Create byte stream let byte_stream = futures::stream::once(async move { @@ -29,7 +31,7 @@ pub async fn upload_image_to_s3( // Upload to S3 client .upload_s3_file( - &job.workspace_id, + workspace_id, s3_key.clone(), None, // storage - use default byte_stream, @@ -45,7 +47,9 @@ pub async fn upload_image_to_s3( }) } -/// Download an S3 image and convert it to a base64 data URL +/// Download an S3 image and convert it to a base64 data URL. +/// +/// The caller must provide an AuthedClient authorized for `workspace_id`. pub async fn download_and_encode_s3_image( image: &S3Object, client: &AuthedClient, @@ -71,6 +75,8 @@ pub async fn download_and_encode_s3_image( } /// Convert an S3Object to the appropriate ContentPart based on MIME type. +/// +/// The caller must provide an AuthedClient authorized for `workspace_id`. pub async fn s3_object_to_content_part( s3_object: &S3Object, client: &AuthedClient, @@ -80,7 +86,7 @@ pub async fn s3_object_to_content_part( download_and_encode_s3_image(s3_object, client, workspace_id).await?; let data_url = format!("data:{};base64,{}", mime_type, file_bytes); - if windmill_ai::ai_types::is_document_mime(&mime_type) { + if crate::ai_types::is_document_mime(&mime_type) { let filename = s3_object .s3 .rsplit('/') @@ -93,7 +99,9 @@ pub async fn s3_object_to_content_part( } } -/// Prepare messages for API by converting S3Objects to base64 ImageUrls +/// Prepare messages for API by converting S3Objects to base64 ImageUrls. +/// +/// The caller must provide an AuthedClient authorized for `workspace_id`. pub async fn prepare_messages_for_api( messages: &[OpenAIMessage], client: &AuthedClient, diff --git a/backend/windmill-ai/src/lib.rs b/backend/windmill-ai/src/lib.rs index dfa34e7d43..945091613b 100644 --- a/backend/windmill-ai/src/lib.rs +++ b/backend/windmill-ai/src/lib.rs @@ -4,5 +4,8 @@ pub mod ai_cache; pub mod ai_google; pub mod ai_providers; pub mod ai_types; +pub mod image_handler; pub mod query_builder; +pub mod sse; pub mod types; +pub mod utils; diff --git a/backend/windmill-worker/src/ai/sse.rs b/backend/windmill-ai/src/sse.rs similarity index 99% rename from backend/windmill-worker/src/ai/sse.rs rename to backend/windmill-ai/src/sse.rs index 2cc03b148e..35a4e43acc 100644 --- a/backend/windmill-worker/src/ai/sse.rs +++ b/backend/windmill-ai/src/sse.rs @@ -3,17 +3,15 @@ use std::collections::HashMap; use eventsource_stream::Eventsource; use reqwest::Response; use serde::Deserialize; -use serde_json; use tokio_stream::StreamExt; -use windmill_ai::{ - ai_google::{parse_gemini_sse_event, GeminiUsageMetadata}, - ai_types::{ExtraContent, GoogleExtraContent, OpenAIFunction, OpenAIToolCall}, -}; use windmill_common::{error::Error, utils::rd_string}; -use crate::ai::{ +use crate::{ + ai_google::{parse_gemini_sse_event, GeminiUsageMetadata}, + ai_types::UrlCitation, + ai_types::{ExtraContent, GoogleExtraContent, OpenAIFunction, OpenAIToolCall}, query_builder::StreamEventSink, - types::{StreamingEvent, UrlCitation}, + types::StreamingEvent, }; #[derive(Deserialize)] @@ -64,6 +62,7 @@ lazy_static::lazy_static! { .parse::() .unwrap_or(false); } +#[allow(async_fn_in_trait)] pub trait SSEParser { async fn parse_event_data(&mut self, data: &str) -> Result<(), Error>; @@ -459,11 +458,11 @@ impl SSEParser for AnthropicSSEParser { // Gemini SSE Parser // ============================================================================ -/// Accumulates Gemini streaming events and converts them into the worker's -/// internal [`OpenAIToolCall`] / [`StreamingEvent`] representation. +/// Accumulates Gemini streaming events and converts them into the shared +/// [`OpenAIToolCall`] / [`StreamingEvent`] representation. /// /// The actual SSE parsing is delegated to [`parse_gemini_sse_event`] from -/// `windmill_common::ai_google` so the logic can be shared with the API proxy. +/// `windmill_ai::ai_google` so the logic can be shared with the API proxy. pub struct GeminiSSEParser { pub accumulated_content: String, pub accumulated_tool_calls: HashMap, diff --git a/backend/windmill-ai/src/utils.rs b/backend/windmill-ai/src/utils.rs new file mode 100644 index 0000000000..b401282df1 --- /dev/null +++ b/backend/windmill-ai/src/utils.rs @@ -0,0 +1,56 @@ +use crate::{ + ai_providers::AIProvider, + ai_types::{ContentPart, OpenAIContent}, +}; + +lazy_static::lazy_static! { + /// Parse AI_HTTP_HEADERS environment variable into a vector of (header_name, header_value) tuples + /// Format: "header1: value1, header2: value2" + pub static ref AI_HTTP_HEADERS: Vec<(String, String)> = { + std::env::var("AI_HTTP_HEADERS") + .ok() + .map(|headers_str| { + headers_str + .split(',') + .filter_map(|header| { + let parts: Vec<&str> = header.splitn(2, ':').collect(); + if parts.len() == 2 { + let name = parts[0].trim().to_string(); + let value = parts[1].trim().to_string(); + if !name.is_empty() && !value.is_empty() { + Some((name, value)) + } else { + None + } + } else { + None + } + }) + .collect() + }) + .unwrap_or_default() + }; +} + +/// AWS Bedrock do not handle structured output query param, so we use a tool for structured output. Same for every Claude models. +pub fn should_use_structured_output_tool(provider: &AIProvider, model: &str) -> bool { + model.contains("claude") || provider == &AIProvider::AWSBedrock +} + +/// Extract text content from OpenAIContent, joining parts with space if multiple +pub fn extract_text_content(content: &OpenAIContent) -> String { + match content { + OpenAIContent::Text(text) => text.clone(), + OpenAIContent::Parts(parts) => parts + .iter() + .filter_map(|p| { + if let ContentPart::Text { text } = p { + Some(text.as_str()) + } else { + None + } + }) + .collect::>() + .join(""), + } +} diff --git a/backend/windmill-api-settings/src/ee_oss.rs b/backend/windmill-api-settings/src/ee_oss.rs index d0e0f69b62..92b3d6ad53 100644 --- a/backend/windmill-api-settings/src/ee_oss.rs +++ b/backend/windmill-api-settings/src/ee_oss.rs @@ -8,7 +8,11 @@ use anyhow::anyhow; pub async fn validate_license_key( _license_key: String, _db: Option<&windmill_common::DB>, -) -> anyhow::Result<(String, bool)> { +) -> anyhow::Result<( + String, + bool, + Option, +)> { // Implementation is not open source Err(anyhow!("License can't be validated in Windmill CE")) } diff --git a/backend/windmill-api-settings/src/lib.rs b/backend/windmill-api-settings/src/lib.rs index f027046808..09b52a3d22 100644 --- a/backend/windmill-api-settings/src/lib.rs +++ b/backend/windmill-api-settings/src/lib.rs @@ -37,13 +37,13 @@ use axum::{ use serde_json::json; use serde::{Deserialize, Serialize}; +use windmill_ai::ai_cache::bump_instance_ai_config_revision; #[cfg(feature = "enterprise")] use windmill_common::ee_oss::{send_critical_alert, CriticalAlertKind, CriticalErrorChannel}; #[cfg(all(feature = "private", feature = "enterprise"))] use windmill_common::secret_backend::{ AwsSecretsManagerSettings, AzureKeyVaultSettings, SecretMigrationReport, VaultSettings, }; -use windmill_ai::ai_cache::bump_instance_ai_config_revision; use windmill_common::{ email_oss::send_email_plain_text, error::{self, JsonResult, Result}, @@ -118,6 +118,8 @@ pub fn global_service() -> Router { get(get_latest_key_renewal_attempt), ) .route("/renew_license_key", post(renew_license_key)) + .route("/offline_license_status", get(get_offline_license_status)) + .route("/instance_hash", get(get_instance_hash)) .route("/customer_portal", post(create_customer_portal_session)) .route("/test_critical_channels", post(test_critical_channels)) .route("/critical_alerts", get(get_critical_alerts)) @@ -340,7 +342,7 @@ pub async fn test_license_key( Json(TestKey { license_key }): Json, ) -> error::Result { require_super_admin(&db, &authed.email).await?; - let (_, expired) = validate_license_key(license_key, Some(&db)).await?; + let (_, expired, _offline_meta) = validate_license_key(license_key, Some(&db)).await?; if expired { Err(error::Error::BadRequest("Expired license key".to_string())) @@ -349,6 +351,53 @@ pub async fn test_license_key( } } +#[derive(serde::Serialize)] +pub struct InstanceHash { + pub instance_hash: Option, +} + +/// Returns the live cap status for an offline license, or `null` when no +/// offline license is loaded. Used by the superadmin settings panel. +pub async fn get_offline_license_status( + Extension(db): Extension, + authed: ApiAuthed, +) -> error::JsonResult> { + require_super_admin(&db, &authed.email).await?; + + let offline = (**windmill_common::ee_oss::LICENSE_OFFLINE_METADATA.load()).clone(); + let is_offline = matches!(&offline, Some(m) if m.is_offline()); + + if !is_offline { + return Ok(Json(None)); + } + + #[cfg(feature = "enterprise")] + let cap = windmill_common::ee_oss::enforce_offline_caps(&db) + .await + .map_err(|e| error::Error::internal_err(format!("enforce_offline_caps: {e:#}")))?; + #[cfg(not(feature = "enterprise"))] + let cap: Option = None; + + Ok(Json(cap)) +} + +/// Returns the per-instance binding hash that goes into offline license keys. +/// Admin invokes via `curl` with their personal token when requesting a key +/// from support. +pub async fn get_instance_hash( + Extension(db): Extension, + authed: ApiAuthed, +) -> error::JsonResult { + require_super_admin(&db, &authed.email).await?; + #[cfg(feature = "enterprise")] + let hash = windmill_common::ee_oss::compute_instance_hash(&db) + .await + .map_err(|e| error::Error::internal_err(format!("compute_instance_hash: {e:#}")))?; + #[cfg(not(feature = "enterprise"))] + let hash: Option = None; + Ok(Json(InstanceHash { instance_hash: hash })) +} + pub async fn get_local_settings( Extension(db): Extension, authed: ApiAuthed, diff --git a/backend/windmill-api-workspaces/src/workspaces.rs b/backend/windmill-api-workspaces/src/workspaces.rs index f479b8c719..95c7157d61 100644 --- a/backend/windmill-api-workspaces/src/workspaces.rs +++ b/backend/windmill-api-workspaces/src/workspaces.rs @@ -5233,6 +5233,13 @@ async fn invite_user( nu.email = nu.email.to_lowercase(); + #[cfg(feature = "enterprise")] + if let Some(msg) = + windmill_common::ee_oss::check_seat_cap_for_new_user(&db, &nu.email, nu.operator).await? + { + return Err(Error::BadRequest(msg)); + } + let mut tx = db.begin().await?; let already_in_workspace = sqlx::query_scalar!( @@ -5306,6 +5313,13 @@ async fn add_user( nu.email = nu.email.to_lowercase(); + #[cfg(feature = "enterprise")] + if let Some(msg) = + windmill_common::ee_oss::check_seat_cap_for_new_user(&db, &nu.email, nu.operator).await? + { + return Err(Error::BadRequest(msg)); + } + let mut tx = db.begin().await?; let already_exists_email = sqlx::query_scalar!( @@ -7351,6 +7365,7 @@ async fn list_ws_specific( WHERE v.workspace_id = s.workspace_id AND v.path = s.path )) ) + ORDER BY s.item_kind, s.path "#, &w_id ) diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 21fdaa2435..e7130e1565 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -1779,6 +1779,63 @@ paths: schema: type: string + /settings/offline_license_status: + get: + summary: get cap-usage status for the currently-loaded offline license + description: | + Returns the live cap status (seats used vs cap, current CU vs cap) for + the offline license key currently in use. Returns `null` if no offline + license is loaded. Super-admin only. + operationId: getOfflineLicenseStatus + tags: + - setting + responses: + "200": + description: cap status (or null when no offline license) + content: + application/json: + schema: + type: object + nullable: true + properties: + seats_used: + type: number + description: Author-equivalent seats consumed (authors + 0.5 × operators) + seats_cap: + type: integer + author_count: + type: integer + operator_count: + type: integer + current_cu: + type: number + description: Sum of CU rate across workers that pinged in the last 2 minutes. + cu_cap: + type: number + cu_over_cap: + type: boolean + + /settings/instance_hash: + get: + summary: per-instance binding hash for offline license issuance + description: | + Returns the hash a superadmin shares with Windmill support when + requesting an offline license. Super-admin only. + operationId: getInstanceHash + tags: + - setting + responses: + '200': + description: instance hash + content: + application/json: + schema: + type: object + properties: + instance_hash: + type: string + nullable: true + /settings/customer_portal: post: summary: create customer portal session @@ -20963,6 +21020,9 @@ components: jwt_role: type: string description: Vault JWT auth role name for Windmill (optional, if not provided token auth is used) + jwt_mount_path: + type: string + description: Mount path for the JWT auth method in Vault (optional, defaults to "jwt"). Set this when the JWT auth method is mounted at a non-default path, e.g. via `vault auth enable -path= jwt`. namespace: type: string description: Vault Enterprise namespace (optional) diff --git a/backend/windmill-api/src/ai.rs b/backend/windmill-api/src/ai.rs index a2c4ceb811..8b415997c2 100644 --- a/backend/windmill-api/src/ai.rs +++ b/backend/windmill-api/src/ai.rs @@ -15,11 +15,12 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, value::RawValue}; use std::collections::HashMap; use std::time::Duration; -use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_ai::ai_cache::current_instance_ai_config_revision; use windmill_ai::ai_providers::{ empty_string_as_none, AIPlatform, AIProvider, ProviderConfig, ProviderModel, }; +use windmill_ai::utils::AI_HTTP_HEADERS; +use windmill_audit::{audit_oss::audit_log, ActionKind}; use windmill_common::db::UserDB; use windmill_common::error::{to_anyhow, Error, Result}; use windmill_common::utils::configure_client; @@ -101,32 +102,6 @@ lazy_static::lazy_static! { pub static ref AI_REQUEST_CACHE: Cache<(String, AIProvider), ExpiringAIRequestConfig> = Cache::new(500); - /// Parse AI_HTTP_HEADERS environment variable into a vector of (header_name, header_value) tuples - /// Format: "header1: value1, header2: value2" - static ref AI_HTTP_HEADERS: Vec<(String, String)> = { - std::env::var("AI_HTTP_HEADERS") - .ok() - .map(|headers_str| { - headers_str - .split(',') - .filter_map(|header| { - let parts: Vec<&str> = header.splitn(2, ':').collect(); - if parts.len() == 2 { - let name = parts[0].trim().to_string(); - let value = parts[1].trim().to_string(); - if !name.is_empty() && !value.is_empty() { - Some((name, value)) - } else { - None - } - } else { - None - } - }) - .collect() - }) - .unwrap_or_default() - }; } pub(crate) fn invalidate_ai_request_cache_for_workspace(workspace_id: &str) { diff --git a/backend/windmill-api/src/ee_oss.rs b/backend/windmill-api/src/ee_oss.rs index a1f7a54d20..e5a7f71cbc 100644 --- a/backend/windmill-api/src/ee_oss.rs +++ b/backend/windmill-api/src/ee_oss.rs @@ -10,7 +10,11 @@ use anyhow::anyhow; pub async fn validate_license_key( _license_key: String, _db: Option<&crate::db::DB>, -) -> anyhow::Result<(String, bool)> { +) -> anyhow::Result<( + String, + bool, + Option, +)> { // Implementation is not open source Err(anyhow!("License can't be validated in Windmill CE")) } diff --git a/backend/windmill-api/src/jobs.rs b/backend/windmill-api/src/jobs.rs index efe03f73dd..ff72ddce70 100644 --- a/backend/windmill-api/src/jobs.rs +++ b/backend/windmill-api/src/jobs.rs @@ -1067,10 +1067,15 @@ impl<'a> GetQuery<'a> { .ok() .inspect(|data| job.raw_flow = Some(sqlx::types::Json(data.raw_flow.clone()))); } - if self.with_code && job.job_kind() == &JobKind::Preview { + if self.with_code + && matches!( + job.job_kind(), + JobKind::Preview | JobKind::FlowScript | JobKind::AppScript + ) + { // Try to fetch the code from the cache, fallback to the preview code. - // NOTE: This could check for the job kinds instead of the `or_else` but it's not - // necessary as `fetch_script` return early if the job kind is not a preview one. + // `fetch_script` resolves FlowScript / AppScript via their runnable_id; for + // Preview jobs it returns early and we fall through to `fetch_preview_script`. let conn = Connection::from(db.clone()); cache::job::fetch_script(db.clone(), job.job_kind(), hash) .or_else(|_| cache::job::fetch_preview_script(&conn, &id, raw_lock, raw_code)) diff --git a/backend/windmill-common/src/ee_oss.rs b/backend/windmill-common/src/ee_oss.rs index 15d9e7cb5e..e68bc00c6e 100644 --- a/backend/windmill-common/src/ee_oss.rs +++ b/backend/windmill-common/src/ee_oss.rs @@ -18,6 +18,60 @@ lazy_static::lazy_static! { pub static ref LICENSE_KEY_VALID: AtomicBool = AtomicBool::new(true); pub static ref LICENSE_KEY_ID: arc_swap::ArcSwap = arc_swap::ArcSwap::from_pointee("".to_string()); pub static ref LICENSE_KEY: arc_swap::ArcSwap = arc_swap::ArcSwap::from_pointee("".to_string()); + pub static ref LICENSE_OFFLINE_METADATA: arc_swap::ArcSwap> = arc_swap::ArcSwap::from_pointee(None); + pub static ref LICENSE_OFFLINE_OVER_CU_CAP: AtomicBool = AtomicBool::new(false); + pub static ref LICENSE_OFFLINE_LAST_STATUS: arc_swap::ArcSwap> = arc_swap::ArcSwap::from_pointee(None); + pub static ref LICENSE_OFFLINE_LAST_CHECKED_AT: arc_swap::ArcSwap>> = arc_swap::ArcSwap::from_pointee(None); +} + +#[cfg(not(feature = "private"))] +#[derive(Clone, Debug, Deserialize, serde::Serialize)] +pub struct OfflineMetadata { + pub v: u32, + pub kind: String, + pub hash: String, + pub seats: i64, + pub cu_limit: f64, +} + +#[cfg(not(feature = "private"))] +impl OfflineMetadata { + pub fn is_offline(&self) -> bool { + self.kind == "offline" + } +} + +#[cfg(not(feature = "private"))] +#[derive(Clone, Debug, serde::Serialize)] +pub struct OfflineCapStatus { + pub seats_used: f64, + pub seats_cap: i64, + pub author_count: i64, + pub operator_count: i64, + pub current_cu: f64, + pub cu_cap: f64, + pub cu_over_cap: bool, +} + +#[cfg(all(feature = "enterprise", not(feature = "private")))] +pub async fn check_seat_cap_for_new_user( + _db: &DB, + _email: &str, + _new_user_is_operator: bool, +) -> anyhow::Result> { + Ok(None) +} + +#[cfg(all(feature = "enterprise", not(feature = "private")))] +pub async fn compute_instance_hash(_db: &DB) -> anyhow::Result> { + // Implementation is not open source + Ok(None) +} + +#[cfg(all(feature = "enterprise", not(feature = "private")))] +pub async fn enforce_offline_caps(_db: &DB) -> anyhow::Result> { + // Implementation is not open source + Ok(None) } #[cfg(not(feature = "private"))] diff --git a/backend/windmill-common/src/lib.rs b/backend/windmill-common/src/lib.rs index 7c7e3f79ed..39884e3d35 100644 --- a/backend/windmill-common/src/lib.rs +++ b/backend/windmill-common/src/lib.rs @@ -121,6 +121,36 @@ pub const PRIVATE_HUB_MIN_VERSION: i32 = 10_000_000; pub const SERVICE_LOG_RETENTION_SECS: i64 = 60 * 60 * 24 * 14; // 2 weeks retention period for logs pub const WM_DEPLOYERS_GROUP: &str = "wm_deployers"; +/// Canonical form of a base URL, used as one of the inputs to the offline-license +/// instance hash (`compute_instance_hash`). +/// +/// Rules: lowercase scheme and host, drop default ports (80/443), strip path/query/fragment, +/// strip trailing slash. If URL parsing fails, falls back to a best-effort lowercase + +/// trailing-slash strip so two semantically-equivalent inputs still produce the same +/// canonical form. +pub fn canonical_base_url(input: &str) -> String { + let trimmed = input.trim(); + if trimmed.is_empty() { + return String::new(); + } + match url::Url::parse(trimmed) { + Ok(u) => { + let scheme = u.scheme().to_ascii_lowercase(); + let host = u + .host_str() + .map(|h| h.to_ascii_lowercase()) + .unwrap_or_default(); + let port = match (u.port(), scheme.as_str()) { + (Some(80), "http") | (Some(443), "https") => String::new(), + (Some(p), _) => format!(":{p}"), + (None, _) => String::new(), + }; + format!("{scheme}://{host}{port}") + } + Err(_) => trimmed.trim_end_matches('/').to_ascii_lowercase(), + } +} + /// Checks if the user is allowed to preserve on_behalf_of values (admin or deployer). pub fn can_preserve_on_behalf_of(authed: &impl db::Authable) -> bool { authed.is_admin() || authed.groups().iter().any(|g| g == &WM_DEPLOYERS_GROUP) diff --git a/backend/windmill-common/src/secret_backend/mod.rs b/backend/windmill-common/src/secret_backend/mod.rs index a75f51ea70..36f35f0cf8 100644 --- a/backend/windmill-common/src/secret_backend/mod.rs +++ b/backend/windmill-common/src/secret_backend/mod.rs @@ -122,6 +122,11 @@ pub struct VaultSettings { /// Optional - if not provided, token auth is used #[serde(skip_serializing_if = "Option::is_none")] pub jwt_role: Option, + /// Mount path for the JWT auth method in Vault (defaults to "jwt"). + /// Set this when the JWT auth method is mounted at a non-default path, + /// e.g. via `vault auth enable -path=my-mount jwt`. + #[serde(skip_serializing_if = "Option::is_none")] + pub jwt_mount_path: Option, /// Vault Enterprise namespace (optional) #[serde(skip_serializing_if = "Option::is_none")] pub namespace: Option, diff --git a/backend/windmill-common/src/secret_backend/tests.rs b/backend/windmill-common/src/secret_backend/tests.rs index 630b6cf023..3e2a12382a 100644 --- a/backend/windmill-common/src/secret_backend/tests.rs +++ b/backend/windmill-common/src/secret_backend/tests.rs @@ -26,6 +26,7 @@ mod tests { address: "http://127.0.0.1:8200".to_string(), mount_path: "windmill".to_string(), jwt_role: Some("windmill-secrets".to_string()), + jwt_mount_path: None, namespace: None, token: Some("test-root-token".to_string()), skip_ssl_verify: None, diff --git a/backend/windmill-common/src/utils.rs b/backend/windmill-common/src/utils.rs index efe5481e1d..17d9cfd804 100644 --- a/backend/windmill-common/src/utils.rs +++ b/backend/windmill-common/src/utils.rs @@ -447,7 +447,9 @@ pub async fn get_license_id_or_uid<'c, E: sqlx::Executor<'c, Database = Postgres } } -async fn get_instance_uid<'c, E: sqlx::Executor<'c, Database = Postgres>>(db: E) -> Result { +pub async fn get_instance_uid<'c, E: sqlx::Executor<'c, Database = Postgres>>( + db: E, +) -> Result { let uid_value = sqlx::query_scalar!( "SELECT value FROM global_settings WHERE name = $1", UNIQUE_ID_SETTING diff --git a/backend/windmill-common/tests/secret_backend_integration.rs b/backend/windmill-common/tests/secret_backend_integration.rs index 070c70defa..350fc297af 100644 --- a/backend/windmill-common/tests/secret_backend_integration.rs +++ b/backend/windmill-common/tests/secret_backend_integration.rs @@ -91,6 +91,7 @@ mod tests { .unwrap_or_else(|_| "http://127.0.0.1:8200".to_string()), mount_path: "windmill".to_string(), jwt_role: None, // Static token mode + jwt_mount_path: None, namespace: None, token: Some( std::env::var("VAULT_TOKEN").unwrap_or_else(|_| "test-root-token".to_string()), @@ -106,6 +107,7 @@ mod tests { .unwrap_or_else(|_| "http://127.0.0.1:8200".to_string()), mount_path: "windmill".to_string(), jwt_role: Some("windmill-secrets".to_string()), // JWT mode + jwt_mount_path: None, namespace: None, token: None, // No static token - use JWT skip_ssl_verify: None, @@ -203,7 +205,10 @@ mod tests { println!("Testing Vault connection with JWT auth..."); println!(" Address: {}", settings.address); println!(" JWT Role: {:?}", settings.jwt_role); - println!(" BASE_URL: {}", (**windmill_common::BASE_URL.load()).clone()); + println!( + " BASE_URL: {}", + (**windmill_common::BASE_URL.load()).clone() + ); let result = test_vault_connection(&settings, Some(&db)).await; assert!( @@ -274,13 +279,15 @@ mod tests { // Encrypt fixture placeholders with real workspace keys encrypt_fixture_secrets(&db).await; - let secret_count = sqlx::query_scalar!( - "SELECT COUNT(*) FROM variable WHERE is_secret = true" - ) - .fetch_one(&db) - .await - .expect("Failed to count secrets"); - println!("Found {} secrets in database before migration", secret_count.unwrap_or(0)); + let secret_count = + sqlx::query_scalar!("SELECT COUNT(*) FROM variable WHERE is_secret = true") + .fetch_one(&db) + .await + .expect("Failed to count secrets"); + println!( + "Found {} secrets in database before migration", + secret_count.unwrap_or(0) + ); // Run migration println!("Migrating secrets to Vault..."); @@ -288,8 +295,10 @@ mod tests { .await .expect("Migration to Vault failed"); - println!("Migration report: total={}, migrated={}, failed={}", - report.total_secrets, report.migrated_count, report.failed_count); + println!( + "Migration report: total={}, migrated={}, failed={}", + report.total_secrets, report.migrated_count, report.failed_count + ); if !report.failures.is_empty() { for f in &report.failures { @@ -307,7 +316,11 @@ mod tests { .get_secret(ws, path) .await .unwrap_or_else(|e| panic!("Failed to read {}/{} from Vault: {:?}", ws, path, e)); - assert_eq!(value, expected_plaintext, "Vault value mismatch for {}/{}", ws, path); + assert_eq!( + value, expected_plaintext, + "Vault value mismatch for {}/{}", + ws, path + ); println!(" ✓ {}/{} correct in Vault", ws, path); } @@ -346,8 +359,10 @@ mod tests { .await .expect("Migration to database failed"); - println!("Migration report: total={}, migrated={}, failed={}", - report.total_secrets, report.migrated_count, report.failed_count); + println!( + "Migration report: total={}, migrated={}, failed={}", + report.total_secrets, report.migrated_count, report.failed_count + ); assert_eq!(report.failed_count, 0, "Migration had failures"); assert!(report.migrated_count > 0, "No secrets were migrated"); @@ -364,7 +379,11 @@ mod tests { let mc = build_crypt(&db, ws).await.unwrap(); let decrypted = decrypt(&mc, row).expect("Failed to decrypt restored value"); - assert_eq!(decrypted, expected_plaintext, "Restored value mismatch for {}/{}", ws, path); + assert_eq!( + decrypted, expected_plaintext, + "Restored value mismatch for {}/{}", + ws, path + ); println!(" ✓ {}/{} correctly restored in DB", ws, path); } @@ -488,11 +507,19 @@ mod tests { .await .unwrap_or_else(|_| panic!("Secret {}/{} not found after round-trip", ws, path)); - assert_ne!(encrypted, "ROUND_TRIP_CLEARED", "Secret {}/{} was not restored", ws, path); + assert_ne!( + encrypted, "ROUND_TRIP_CLEARED", + "Secret {}/{} was not restored", + ws, path + ); let mc = build_crypt(&db, ws).await.unwrap(); let decrypted = decrypt(&mc, encrypted).expect("Failed to decrypt"); - assert_eq!(decrypted, expected_plaintext, "Round-trip value mismatch for {}/{}", ws, path); + assert_eq!( + decrypted, expected_plaintext, + "Round-trip value mismatch for {}/{}", + ws, path + ); println!(" ✓ {}/{}: round-trip OK", ws, path); } @@ -522,10 +549,7 @@ mod tests { .get_secret("test-workspace", "u/test-user/other_secret") .await; - assert!( - cross_access.is_err(), - "Cross-workspace access should fail!" - ); + assert!(cross_access.is_err(), "Cross-workspace access should fail!"); println!("✓ Cross-workspace access correctly denied"); // Verify own workspace access works diff --git a/backend/windmill-common/tests/secret_backend_migration.rs b/backend/windmill-common/tests/secret_backend_migration.rs index 1915b90630..fba27ee260 100644 --- a/backend/windmill-common/tests/secret_backend_migration.rs +++ b/backend/windmill-common/tests/secret_backend_migration.rs @@ -23,19 +23,21 @@ use sqlx::{Pool, Postgres}; use windmill_common::error::Result; use windmill_common::secret_backend::{ - vault_oss::{migrate_secrets_to_database, migrate_secrets_to_vault, test_vault_connection, VaultBackend}, + vault_oss::{ + migrate_secrets_to_database, migrate_secrets_to_vault, test_vault_connection, VaultBackend, + }, SecretBackend, VaultSettings, }; fn test_vault_settings() -> VaultSettings { VaultSettings { - address: std::env::var("VAULT_ADDR").unwrap_or_else(|_| "http://127.0.0.1:8200".to_string()), + address: std::env::var("VAULT_ADDR") + .unwrap_or_else(|_| "http://127.0.0.1:8200".to_string()), mount_path: "windmill".to_string(), jwt_role: Some("windmill-secrets".to_string()), + jwt_mount_path: None, namespace: None, - token: Some( - std::env::var("VAULT_TOKEN").unwrap_or_else(|_| "test-root-token".to_string()), - ), + token: Some(std::env::var("VAULT_TOKEN").unwrap_or_else(|_| "test-root-token".to_string())), skip_ssl_verify: None, } } @@ -47,7 +49,11 @@ async fn test_vault_connection_works(db: Pool) { let settings = test_vault_settings(); let result = test_vault_connection(&settings, Some(&db)).await; - assert!(result.is_ok(), "Failed to connect to Vault: {:?}", result.err()); + assert!( + result.is_ok(), + "Failed to connect to Vault: {:?}", + result.err() + ); println!("✓ Successfully connected to Vault at {}", settings.address); } @@ -70,7 +76,10 @@ async fn test_migrate_db_to_vault(db: Pool) { .await .expect("Failed to query secrets"); - println!("Found {} secrets in database before migration:", secrets_before.len()); + println!( + "Found {} secrets in database before migration:", + secrets_before.len() + ); for s in &secrets_before { println!(" - {}/{}: {} chars", s.workspace_id, s.path, s.value.len()); } @@ -111,7 +120,10 @@ async fn test_migrate_db_to_vault(db: Pool) { secret.path, result.err() ); - println!(" ✓ {}/{} exists in Vault", secret.workspace_id, secret.path); + println!( + " ✓ {}/{} exists in Vault", + secret.workspace_id, secret.path + ); } println!("\n✓ Migration to Vault completed successfully"); @@ -133,8 +145,14 @@ async fn test_migrate_vault_to_db(db: Pool) { let to_vault_report = migrate_secrets_to_vault(&db, &settings) .await .expect("Initial migration to Vault failed"); - assert!(to_vault_report.migrated_count > 0, "No secrets to test with"); - println!(" Migrated {} secrets to Vault", to_vault_report.migrated_count); + assert!( + to_vault_report.migrated_count > 0, + "No secrets to test with" + ); + println!( + " Migrated {} secrets to Vault", + to_vault_report.migrated_count + ); // Clear the database values to simulate fresh migration back println!("\nClearing database secret values..."); @@ -150,7 +168,10 @@ async fn test_migrate_vault_to_db(db: Pool) { .fetch_one(&db) .await .expect("Failed to count cleared"); - println!(" Cleared {} secret values in database", cleared.count.unwrap_or(0)); + println!( + " Cleared {} secret values in database", + cleared.count.unwrap_or(0) + ); // Now migrate from Vault back to database println!("\nMigrating secrets from Vault to database..."); @@ -206,15 +227,14 @@ async fn test_full_round_trip_migration(db: Pool) { .expect("Failed to connect to Vault"); // Get original secrets - let original_secrets: std::collections::HashMap<(String, String), String> = sqlx::query!( - "SELECT workspace_id, path, value FROM variable WHERE is_secret = true" - ) - .fetch_all(&db) - .await - .expect("Failed to query original secrets") - .into_iter() - .map(|r| ((r.workspace_id, r.path), r.value)) - .collect(); + let original_secrets: std::collections::HashMap<(String, String), String> = + sqlx::query!("SELECT workspace_id, path, value FROM variable WHERE is_secret = true") + .fetch_all(&db) + .await + .expect("Failed to query original secrets") + .into_iter() + .map(|r| ((r.workspace_id, r.path), r.value)) + .collect(); println!("Original secrets: {} entries", original_secrets.len()); @@ -243,21 +263,23 @@ async fn test_full_round_trip_migration(db: Pool) { // Step 4: Verify round-trip integrity println!("\n=== Step 4: Verify round-trip integrity ==="); - let restored_secrets: std::collections::HashMap<(String, String), String> = sqlx::query!( - "SELECT workspace_id, path, value FROM variable WHERE is_secret = true" - ) - .fetch_all(&db) - .await - .expect("Failed to query restored secrets") - .into_iter() - .map(|r| ((r.workspace_id, r.path), r.value)) - .collect(); + let restored_secrets: std::collections::HashMap<(String, String), String> = + sqlx::query!("SELECT workspace_id, path, value FROM variable WHERE is_secret = true") + .fetch_all(&db) + .await + .expect("Failed to query restored secrets") + .into_iter() + .map(|r| ((r.workspace_id, r.path), r.value)) + .collect(); // Compare original and restored for ((ws, path), _original_value) in &original_secrets { let restored_value = restored_secrets .get(&(ws.clone(), path.clone())) - .expect(&format!("Secret {}/{} not found after round-trip", ws, path)); + .expect(&format!( + "Secret {}/{} not found after round-trip", + ws, path + )); // Note: Values might differ slightly due to encryption/decryption // but they should not be the cleared value @@ -266,7 +288,12 @@ async fn test_full_round_trip_migration(db: Pool) { "Secret {}/{} was not restored", ws, path ); - println!(" ✓ {}/{}: restored ({} chars)", ws, path, restored_value.len()); + println!( + " ✓ {}/{}: restored ({} chars)", + ws, + path, + restored_value.len() + ); } println!("\n✓ Full round-trip migration completed successfully!"); @@ -289,7 +316,10 @@ async fn test_workspace_isolation(db: Pool) { .await .expect("Migration failed"); - println!("Migrated {} secrets across workspaces", report.migrated_count); + println!( + "Migrated {} secrets across workspaces", + report.migrated_count + ); // Verify workspace isolation in Vault let vault_backend = VaultBackend::new(settings.clone()); @@ -309,13 +339,19 @@ async fn test_workspace_isolation(db: Pool) { let ws1_result: Result = vault_backend .get_secret("test-workspace", "u/test-user/db_password") .await; - assert!(ws1_result.is_ok(), "test-workspace secret should be accessible"); + assert!( + ws1_result.is_ok(), + "test-workspace secret should be accessible" + ); println!("✓ test-workspace secrets accessible"); let ws2_result: Result = vault_backend .get_secret("test-workspace-2", "u/test-user/other_secret") .await; - assert!(ws2_result.is_ok(), "test-workspace-2 secret should be accessible"); + assert!( + ws2_result.is_ok(), + "test-workspace-2 secret should be accessible" + ); println!("✓ test-workspace-2 secrets accessible"); println!("\n✓ Workspace isolation verified!"); diff --git a/backend/windmill-runtime-nativets/Cargo.toml b/backend/windmill-runtime-nativets/Cargo.toml index 417ec8de9d..edad615ae5 100644 --- a/backend/windmill-runtime-nativets/Cargo.toml +++ b/backend/windmill-runtime-nativets/Cargo.toml @@ -28,9 +28,9 @@ deno_ast.workspace = true deno_tls.workspace = true deno_permissions.workspace = true deno_io.workspace = true +deno_fs.workspace = true deno_telemetry.workspace = true deno_error.workspace = true -deno_runtime.workspace = true winapi.workspace = true itertools.workspace = true @@ -60,6 +60,7 @@ deno_ast.workspace = true deno_tls.workspace = true deno_permissions.workspace = true deno_io.workspace = true -deno_runtime.workspace = true +deno_fs.workspace = true deno_telemetry.workspace = true +deno_error.workspace = true winapi.workspace = true diff --git a/backend/windmill-runtime-nativets/build.rs b/backend/windmill-runtime-nativets/build.rs index 2f4ec8c38d..8262827815 100644 --- a/backend/windmill-runtime-nativets/build.rs +++ b/backend/windmill-runtime-nativets/build.rs @@ -1,3 +1,6 @@ +use deno_ast::{MediaType, ParseParams}; +use deno_core::{ModuleCodeString, ModuleName, SourceMapData}; +use deno_error::JsErrorBox; use deno_fetch::FetchPermissions; use deno_net::NetPermissions; use deno_web::{BlobStore, TimersPermission}; @@ -22,10 +25,30 @@ impl FetchPermissions for PermissionsContainer { #[inline(always)] fn check_read<'a>( &mut self, - _resolved: bool, - _p: &'a std::path::Path, + _path: Cow<'a, Path>, _api_name: &str, - ) -> Result, deno_io::fs::FsError> { + _get_path: &'a dyn deno_fs::GetPath, + ) -> Result, deno_io::fs::FsError> { + unreachable!("snapshotting") + } + + #[inline(always)] + fn check_write<'a>( + &mut self, + _path: Cow<'a, Path>, + _api_name: &str, + _get_path: &'a dyn deno_fs::GetPath, + ) -> Result, deno_io::fs::FsError> { + unreachable!("snapshotting") + } + + #[inline(always)] + fn check_net_vsock( + &mut self, + _cid: u32, + _port: u32, + _api_name: &str, + ) -> Result<(), deno_permissions::PermissionCheckError> { unreachable!("snapshotting") } } @@ -38,17 +61,17 @@ impl TimersPermission for PermissionsContainer { } impl NetPermissions for PermissionsContainer { - fn check_read<'a>( + fn check_read( &mut self, - _p: &'a str, + _p: &str, _api_name: &str, ) -> Result { unreachable!("snapshotting") } - fn check_write<'a>( + fn check_write( &mut self, - _p: &'a str, + _p: &str, _api_name: &str, ) -> Result { unreachable!("snapshotting") @@ -64,10 +87,19 @@ impl NetPermissions for PermissionsContainer { fn check_write_path<'a>( &mut self, - _: &'a Path, - _: &str, + _p: Cow<'a, Path>, + _api_name: &str, ) -> Result, deno_permissions::PermissionCheckError> { - todo!() + unreachable!("snapshotting") + } + + fn check_vsock( + &mut self, + _cid: u32, + _port: u32, + _api_name: &str, + ) -> Result<(), deno_permissions::PermissionCheckError> { + unreachable!("snapshotting") } } @@ -77,22 +109,87 @@ deno_core::extension!( esm = ["src/runtime.js"], ); +// `extension_transpiler` callback for `deno_core::snapshot::create_snapshot`. +// +// Specialized to our snapshot's inputs. Of the seven deno_* extensions +// we register via `init()`, six ship pre-built `.js` files +// in their `esm` lists (webidl/url/console/web/fetch/net) — only +// `deno_telemetry`'s `extension!` macro lists `.ts` files +// (`telemetry.ts`, `util.ts`), so the TypeScript branch is needed +// solely for that crate. Our local `fetch` extension contributes +// `src/runtime.js` (pure JS). No `node:` imports happen at snapshot +// build time, no `.mjs`, no user-supplied modules. So: +// - `.js` → pass through. +// - `.ts` → transpile via deno_ast (deno_telemetry only). +// - anything else → build bug (deno shipping an unexpected file type +// or us mislabelling one), panic loudly rather than emit a broken +// snapshot. +// +// No source maps: the snapshot is a binary blob the runtime loads — source +// maps would never be consumed. +// +// The signature still returns `Result<_, JsErrorBox>` because that's what +// `extension_transpiler` expects, but we never construct one — parse and +// transpile failures are build-time bugs in deno's own .ts internals (or +// in our runtime.js, if we ever change its extension), so they panic. +// +// This replaces a call to `deno_runtime::transpile::maybe_transpile_source` +// from `deno_runtime 0.198.0`. The original is more general (handles +// `node:` modules, `.mjs`, emits source maps in debug builds, plumbs +// errors via `JsErrorBox`); none of that surface is reachable in our +// build. Dropping the `deno_runtime` dep eliminates a +// `deno_cache → rusqlite → libsqlite3-sys 0.35` transitive chain that +// collides with sqlx-sqlite's `libsqlite3-sys 0.30` (cargo's +// `links = "sqlite3"` rule). +fn maybe_transpile_source( + name: ModuleName, + source: ModuleCodeString, +) -> Result<(ModuleCodeString, Option), JsErrorBox> { + let media_type = MediaType::from_path(Path::new(&name)); + match media_type { + MediaType::JavaScript => return Ok((source, None)), + MediaType::TypeScript => {} + _ => panic!("unexpected media type {media_type:?} for {name} during snapshot build"), + } + + let parsed = deno_ast::parse_module(ParseParams { + specifier: deno_core::url::Url::parse(&name).unwrap(), + text: source.into(), + media_type, + capture_tokens: false, + scope_analysis: false, + maybe_syntax: None, + }) + .unwrap_or_else(|e| panic!("snapshot transpile: parse failed for {name}: {e}")); + + let transpiled = parsed + .transpile( + &deno_ast::TranspileOptions { + imports_not_used_as_values: deno_ast::ImportsNotUsedAsValues::Remove, + ..Default::default() + }, + &deno_ast::TranspileModuleOptions::default(), + &deno_ast::EmitOptions::default(), + ) + .unwrap_or_else(|e| panic!("snapshot transpile: emit failed for {name}: {e}")) + .into_source(); + + Ok((transpiled.text.into(), None)) +} + fn main() { println!("cargo:rustc-env=TARGET={}", env::var("TARGET").unwrap()); println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap()); let exts = vec![ - deno_telemetry::deno_telemetry::init_ops_and_esm(), - deno_webidl::deno_webidl::init_ops_and_esm(), - deno_url::deno_url::init_ops_and_esm(), - deno_console::deno_console::init_ops_and_esm(), - deno_web::deno_web::init_ops_and_esm::( - Arc::new(BlobStore::default()), - None, - ), - deno_fetch::deno_fetch::init_ops_and_esm::(Default::default()), - deno_net::deno_net::init_ops_and_esm::(None, None), - fetch::init_ops_and_esm(), + deno_telemetry::deno_telemetry::init(), + deno_webidl::deno_webidl::init(), + deno_url::deno_url::init(), + deno_console::deno_console::init(), + deno_web::deno_web::init::(Arc::new(BlobStore::default()), None), + deno_fetch::deno_fetch::init::(Default::default()), + deno_net::deno_net::init::(None, None), + fetch::init(), ]; // Build the file path to the snapshot. @@ -105,7 +202,7 @@ fn main() { cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), startup_snapshot: None, extension_transpiler: Some(std::rc::Rc::new(|specifier, source| { - deno_runtime::transpile::maybe_transpile_source(specifier, source) + maybe_transpile_source(specifier, source) })), extensions: exts, with_runtime_cb: None, diff --git a/backend/windmill-runtime-nativets/src/lib.rs b/backend/windmill-runtime-nativets/src/lib.rs index dda57ae708..52e23f11da 100644 --- a/backend/windmill-runtime-nativets/src/lib.rs +++ b/backend/windmill-runtime-nativets/src/lib.rs @@ -15,6 +15,9 @@ mod dedicated; pub use dedicated::{ExecutingIsolate, PrewarmedIsolate, PrewarmedResult}; +#[cfg(test)] +mod smoke_tests; + use std::{ borrow::Cow, cell::RefCell, @@ -47,6 +50,28 @@ use windmill_common::error::Error; use windmill_common::result_stream::append_result_stream_db; use windmill_common::worker::{write_file, Connection, WINDMILL_DIR}; +// ── Snapshot-matched extensions ────────────────────────────────────── +// +// `deno_core` 0.352 validates that the snapshot's extension list is a +// *prefix* of the runtime's extension list (snapshot does not need an +// exact match — runtime is allowed to add extensions at the tail, but +// must not reorder or omit any that the snapshot baked in). +// +// Our snapshot (in build.rs) is the same eight deno_* extensions ending +// with this local `fetch` ext. The runtime adds one extra entry at the +// end — the windmill `ext` carrying our own ops — which is fine because +// it's after the snapshot prefix. +// +// This local `fetch` extension declaration must be present in both +// build.rs and lib.rs so the type passes through the `init()` macro. +// The ESM is already in the snapshot, so this `init()` call at runtime +// is a no-op for esm — the registration just records the ext. +deno_core::extension!( + fetch, + esm_entry_point = "ext:fetch/src/runtime.js", + esm = ["src/runtime.js"], +); + // ── Permission container ───────────────────────────────────────────── pub struct PermissionsContainer; @@ -64,11 +89,31 @@ impl FetchPermissions for PermissionsContainer { #[inline(always)] fn check_read<'a>( &mut self, - _resolved: bool, - p: &'a std::path::Path, + path: Cow<'a, std::path::Path>, _api_name: &str, - ) -> Result, deno_io::fs::FsError> { - Ok(Cow::Borrowed(p)) + _get_path: &'a dyn deno_fs::GetPath, + ) -> Result, deno_io::fs::FsError> { + Ok(deno_fs::CheckedPath::Unresolved(path)) + } + + #[inline(always)] + fn check_write<'a>( + &mut self, + path: Cow<'a, std::path::Path>, + _api_name: &str, + _get_path: &'a dyn deno_fs::GetPath, + ) -> Result, deno_io::fs::FsError> { + Ok(deno_fs::CheckedPath::Unresolved(path)) + } + + #[inline(always)] + fn check_net_vsock( + &mut self, + _cid: u32, + _port: u32, + _api_name: &str, + ) -> Result<(), deno_permissions::PermissionCheckError> { + Ok(()) } } @@ -80,17 +125,17 @@ impl TimersPermission for PermissionsContainer { } impl NetPermissions for PermissionsContainer { - fn check_read<'a>( + fn check_read( &mut self, - p: &'a str, + p: &str, _api_name: &str, ) -> Result { Ok(PathBuf::from(p)) } - fn check_write<'a>( + fn check_write( &mut self, - p: &'a str, + p: &str, _api_name: &str, ) -> Result { Ok(PathBuf::from(p)) @@ -106,10 +151,19 @@ impl NetPermissions for PermissionsContainer { fn check_write_path<'a>( &mut self, - p: &'a std::path::Path, + p: Cow<'a, std::path::Path>, _api_name: &str, - ) -> Result, deno_permissions::PermissionCheckError> { - Ok(Cow::Borrowed(p)) + ) -> Result, deno_permissions::PermissionCheckError> { + Ok(p) + } + + fn check_vsock( + &mut self, + _cid: u32, + _port: u32, + _api_name: &str, + ) -> Result<(), deno_permissions::PermissionCheckError> { + Ok(()) } } @@ -381,7 +435,7 @@ pub(crate) fn create_nativets_runtime( let fetch_options = deno_fetch::Options { root_cert_store_provider: None, user_agent: ann.useragent.unwrap_or_else(|| "windmill/beta".to_string()), - proxy: ann.proxy.map(|x| deno_tls::Proxy { + proxy: ann.proxy.map(|x| deno_tls::Proxy::Http { url: x.0, basic_auth: x .1 @@ -391,13 +445,14 @@ pub(crate) fn create_nativets_runtime( }; let exts: Vec = vec![ - deno_telemetry::deno_telemetry::init_ops(), - deno_webidl::deno_webidl::init_ops(), - deno_url::deno_url::init_ops(), - deno_console::deno_console::init_ops(), - deno_web::deno_web::init_ops::(Arc::new(BlobStore::default()), None), - deno_fetch::deno_fetch::init_ops::(fetch_options), - deno_net::deno_net::init_ops::(None, None), + deno_telemetry::deno_telemetry::init(), + deno_webidl::deno_webidl::init(), + deno_url::deno_url::init(), + deno_console::deno_console::init(), + deno_web::deno_web::init::(Arc::new(BlobStore::default()), None), + deno_fetch::deno_fetch::init::(fetch_options), + deno_net::deno_net::init::(None, None), + fetch::init(), ext, ]; diff --git a/backend/windmill-runtime-nativets/src/smoke_tests.rs b/backend/windmill-runtime-nativets/src/smoke_tests.rs new file mode 100644 index 0000000000..20675ee2a7 --- /dev/null +++ b/backend/windmill-runtime-nativets/src/smoke_tests.rs @@ -0,0 +1,280 @@ +//! Opt-in smoke tests for the nativets V8 runtime. +//! +//! Exercise the deno_core / deno_ast / swc surface (TypeScript transpile, +//! fetch, timers, URL, structuredClone, error propagation, concurrent +//! isolates, large payload roundtrip) that the standard worker-level +//! nativets tests in `backend/tests/worker.rs` don't reach — those tests +//! validate value passing through the job queue, but not the JS API +//! surface a deno_core bump would actually move. +//! +//! These tests are `#[ignore]`'d so the regular `cargo test` flow doesn't +//! pay their cost (each spawns a V8 isolate; some hit the network). Run +//! when changing the `deno_core` / `deno_ast` / `deno_runtime` / `swc_*` +//! pins in `backend/Cargo.toml`: +//! +//! cargo test -p windmill-runtime-nativets smoke -- --ignored +//! +//! Tests prefixed `smoke_net_` hit the public internet (httpbin.org, +//! example.com) and will fail if the runner has no egress. Skip them +//! locally with `cargo test -p windmill-runtime-nativets smoke -- --ignored --skip smoke_net_`. + +use crate::{transpile_ts, NativeAnnotation, PrewarmedIsolate, PrewarmedResult}; + +/// Compile a TS snippet, run it through a fresh isolate with the given +/// positional args, and return the isolate's result + captured logs. +async fn run_ts(ts: &str, arg_names: &[&str], args: serde_json::Value) -> PrewarmedResult { + let js = transpile_ts(ts.to_string()).expect("transpile_ts failed"); + let ann = NativeAnnotation { useragent: None, proxy: None }; + let arg_names: Vec = arg_names.iter().map(|s| s.to_string()).collect(); + let mut iso = PrewarmedIsolate::spawn(String::new(), js, ann, arg_names, None); + iso.wait_ready().await.expect("isolate failed to pre-warm"); + iso.start_execution(args.to_string()) + .wait() + .await + .expect("isolate execution panicked") +} + +fn unwrap_value(r: &PrewarmedResult) -> serde_json::Value { + let raw = r.result.as_ref().expect("script returned an error"); + serde_json::from_str(raw.get()).expect("result not valid JSON") +} + +// ----------------------------------------------------------------------------- +// Local (no network) — these still need V8 / deno_core ops to be wired. +// ----------------------------------------------------------------------------- + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_basic_value_passing() { + let ts = r#" +export async function main(x: number): Promise { + return x + 1; +} +"#; + let r = run_ts(ts, &["x"], serde_json::json!({"x": 41})).await; + assert_eq!(unwrap_value(&r), serde_json::json!(42)); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_transpile_enum_and_union() { + // Enums + discriminated union + as-cast exercise the swc_ecma_ast + + // swc_ecma_parser TS-syntax paths the bare value tests don't. + let ts = r#" +enum Direction { Up = "U", Down = "D" } +type Msg = { kind: "move"; dir: Direction } | { kind: "stop" }; +export async function main(): Promise { + const msgs: Msg[] = [ + { kind: "move", dir: Direction.Up }, + { kind: "stop" }, + { kind: "move", dir: Direction.Down }, + ]; + return msgs.map(m => m.kind === "move" ? m.dir : "_").join(","); +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + assert_eq!(unwrap_value(&r), serde_json::json!("U,_,D")); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_set_timeout_and_promise_all() { + // setTimeout lives in deno_web; Promise.all hits the V8 microtask + // queue. A bump that breaks timer-op registration or microtask drain + // would surface here (script would hang or return wrong order). + let ts = r#" +export async function main(): Promise { + const delays = [40, 10, 20, 30]; + return await Promise.all(delays.map(d => + new Promise(resolve => setTimeout(() => resolve(d), d)) + )); +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + // Promise.all preserves input order regardless of resolution order. + assert_eq!(unwrap_value(&r), serde_json::json!([40, 10, 20, 30])); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_url_and_searchparams() { + // deno_url surface: URL ctor, URLSearchParams parsing + iteration. + let ts = r#" +export async function main(): Promise<{ host: string; pairs: [string, string][] }> { + const u = new URL("https://example.com:8443/path?b=2&a=1&a=3"); + const pairs: [string, string][] = []; + for (const [k, v] of u.searchParams) pairs.push([k, v]); + return { host: u.host, pairs }; +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + assert_eq!( + unwrap_value(&r), + serde_json::json!({ + "host": "example.com:8443", + "pairs": [["b", "2"], ["a", "1"], ["a", "3"]], + }), + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_web_blob_btoa_atob() { + // deno_web surface: Blob, atob/btoa. `structuredClone` is *not* wired + // into the nativets global (the deno_web binding doesn't expose it + // here) — if that's ever changed, extend this test to cover it. + let ts = r#" +export async function main(): Promise<{ b64: string; round_trip: string; size: number }> { + const blob = new Blob(["hello"], { type: "text/plain" }); + const b64 = btoa("hello"); + const round_trip = atob(b64); + return { b64, round_trip, size: blob.size }; +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + assert_eq!( + unwrap_value(&r), + serde_json::json!({ + "b64": "aGVsbG8=", + "round_trip": "hello", + "size": 5, + }), + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_large_payload_roundtrip() { + // ~512 KB string in and out — exercises arg encoding + result + // serialization through the deno_core <-> host op boundary at sizes + // an op-table change could break. + let big_in: String = "a".repeat(512 * 1024); + let ts = r#" +export async function main(s: string): Promise<{ in_len: number; out: string }> { + if (typeof s !== "string") throw new Error(`expected string, got ${typeof s}`); + return { in_len: s.length, out: "b".repeat(512 * 1024) }; +} +"#; + let r = run_ts(ts, &["s"], serde_json::json!({"s": big_in})).await; + let v = unwrap_value(&r); + assert_eq!(v.get("in_len").and_then(|x| x.as_u64()), Some(512 * 1024)); + let out_len = v + .get("out") + .and_then(|x| x.as_str()) + .map(|s| s.len()) + .unwrap_or(0); + assert_eq!(out_len, 512 * 1024); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_error_propagation_with_message() { + // Throwing a typed Error must surface as PrewarmedResult::Err with + // the original message. A deno_core bump that changes the host-side + // error wrapping would lose this contract. + let ts = r#" +export async function main(): Promise { + throw new Error("nativets_smoke_marker_xyz"); +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + let err = r.result.expect_err("expected script to fail"); + assert!( + err.contains("nativets_smoke_marker_xyz"), + "thrown error message did not reach result: {err}", + ); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +#[ignore = "deno_core upgrade smoke; run with --ignored"] +async fn smoke_concurrent_isolates() { + // Spawn N isolates in parallel from the same tokio runtime. Each + // PrewarmedIsolate uses spawn_blocking + a fresh V8 isolate. + // Catches isolate-setup races (V8_ISOLATE_CREATE_LOCK ordering) and + // any per-isolate state that a deno_core bump could break under + // concurrency. + let ts = r#" +export async function main(i: number): Promise { + return i * 10; +} +"#; + let js = transpile_ts(ts.to_string()).expect("transpile_ts failed"); + + const N: i64 = 8; + let mut handles = Vec::with_capacity(N as usize); + for i in 0..N { + let js = js.clone(); + let h = tokio::spawn(async move { + let ann = NativeAnnotation { useragent: None, proxy: None }; + let mut iso = + PrewarmedIsolate::spawn(String::new(), js, ann, vec!["i".to_string()], None); + iso.wait_ready().await.expect("pre-warm failed"); + let res = iso + .start_execution(serde_json::json!({"i": i}).to_string()) + .wait() + .await + .expect("isolate panicked"); + res.result.expect("script errored") + }); + handles.push(h); + } + + let mut got: Vec = Vec::with_capacity(N as usize); + for h in handles { + let raw = h.await.expect("join failed"); + let v: serde_json::Value = serde_json::from_str(raw.get()).expect("not JSON"); + got.push(v.as_i64().unwrap_or(-1)); + } + got.sort(); + let expected: Vec = (0..N).map(|i| i * 10).collect(); + assert_eq!(got, expected); +} + +// ----------------------------------------------------------------------------- +// Network — actually exercise deno_fetch end-to-end. Skip in air-gapped CI +// with `--skip smoke_net_`. +// ----------------------------------------------------------------------------- + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke (network); run with --ignored"] +async fn smoke_net_fetch_example_com() { + // example.com is one of the most stable hosts on the internet and + // returns a tiny known-text body, so we can both assert "fetch works" + // and "the response body parses correctly through deno_fetch". + let ts = r#" +export async function main(): Promise<{ status: number; has_marker: boolean }> { + const r = await fetch("https://example.com/"); + const body = await r.text(); + return { status: r.status, has_marker: body.includes("Example Domain") }; +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + let v = unwrap_value(&r); + assert_eq!(v.get("status").and_then(|x| x.as_u64()), Some(200)); + assert_eq!(v.get("has_marker"), Some(&serde_json::json!(true))); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +#[ignore = "deno_core upgrade smoke (network); run with --ignored"] +async fn smoke_net_fetch_json_and_headers() { + // httpbin.org/anything echoes request metadata back as JSON, so we + // can verify: deno_fetch sends custom headers, parses JSON response, + // and propagates query params end-to-end. + let ts = r#" +export async function main(): Promise<{ ua: string; arg: string }> { + const r = await fetch("https://httpbin.org/anything?nativets=ok", { + headers: { "x-windmill-smoke": "1" }, + }); + if (!r.ok) throw new Error(`status ${r.status}`); + const j: any = await r.json(); + return { + ua: j.headers["X-Windmill-Smoke"] ?? "", + arg: j.args.nativets ?? "", + }; +} +"#; + let r = run_ts(ts, &[], serde_json::json!({})).await; + let v = unwrap_value(&r); + assert_eq!(v.get("ua").and_then(|x| x.as_str()), Some("1")); + assert_eq!(v.get("arg").and_then(|x| x.as_str()), Some("ok")); +} diff --git a/backend/windmill-store/src/resources.rs b/backend/windmill-store/src/resources.rs index 6b169a0c0d..8aa88bad86 100644 --- a/backend/windmill-store/src/resources.rs +++ b/backend/windmill-store/src/resources.rs @@ -1238,10 +1238,39 @@ async fn delete_resources_bulk( .await?; if let Some(res_data) = trash_resource { + // Per-resource linked vars so each resource's trash entry carries + // exactly the variables that vanished with it (matching the + // single-delete shape: trash_data["linked_variables"]). + let mut this_linked: Vec = Vec::new(); if let Some(value) = res_data.get("value") { - collect_var_refs(value, &mut linked_var_paths); + collect_var_refs(value, &mut this_linked); + } + this_linked.sort(); + this_linked.dedup(); + + let trash_linked_vars: Vec = if this_linked.is_empty() { + Vec::new() + } else { + let placeholders: Vec = this_linked + .iter() + .enumerate() + .map(|(i, _)| format!("${}", i + 2)) + .collect(); + let query = format!( + "SELECT to_jsonb(t) FROM variable t WHERE workspace_id = $1 AND path IN ({})", + placeholders.join(", ") + ); + let mut q = sqlx::query_scalar::<_, serde_json::Value>(&query).bind(&w_id); + for var_path in &this_linked { + q = q.bind(var_path); + } + q.fetch_all(&mut *tx).await? + }; + + let mut trash_data = serde_json::json!({"row": res_data}); + if !trash_linked_vars.is_empty() { + trash_data["linked_variables"] = serde_json::Value::Array(trash_linked_vars); } - let trash_data = serde_json::json!({"row": res_data}); windmill_common::trashbin::move_to_trash( &mut *tx, &w_id, @@ -1251,6 +1280,8 @@ async fn delete_resources_bulk( &authed.username, ) .await?; + + linked_var_paths.extend(this_linked); } } linked_var_paths.sort(); diff --git a/backend/windmill-store/src/variables.rs b/backend/windmill-store/src/variables.rs index a9f8734647..c50049fcd6 100644 --- a/backend/windmill-store/src/variables.rs +++ b/backend/windmill-store/src/variables.rs @@ -755,6 +755,17 @@ async fn delete_variables_bulk( ) .fetch_all(&mut *tx) .await?; + // Mirror single delete_variable: clean the linked-resource ws_specific + // markers BEFORE deleting the resource rows so they don't survive as + // orphans. A resource later created at the same path would otherwise + // inherit a stale ws_specific flag. + sqlx::query!( + "DELETE FROM ws_specific WHERE workspace_id = $1 AND item_kind = 'resource' AND path = ANY($2)", + w_id, + &deleted_paths + ) + .execute(&mut *tx) + .await?; sqlx::query!( "DELETE FROM resource WHERE path = ANY($1) AND workspace_id = $2", &deleted_paths, @@ -1019,6 +1030,20 @@ async fn update_variable( ) .execute(&mut *tx) .await?; + + // The linked resource at the same path is renamed above; move + // its ws_specific 'resource' marker too so an explicitly-flagged + // resource doesn't lose its ws_specific status on rename and + // doesn't leave a stale marker at the old path. Symmetric with + // update_resource's rename block. + sqlx::query!( + "UPDATE ws_specific SET path = $1 WHERE workspace_id = $2 AND item_kind = 'resource' AND path = $3", + npath, + w_id, + path + ) + .execute(&mut *tx) + .await?; } } diff --git a/backend/windmill-worker/src/ai/mod.rs b/backend/windmill-worker/src/ai/mod.rs index 4ad67b9e6e..b004b0ec20 100644 --- a/backend/windmill-worker/src/ai/mod.rs +++ b/backend/windmill-worker/src/ai/mod.rs @@ -1,10 +1,7 @@ // AI executor module structure // This module will contain all AI-related execution logic -pub mod image_handler; pub mod providers; pub mod query_builder; -pub mod sse; pub mod tools; -pub mod types; pub mod utils; diff --git a/backend/windmill-worker/src/ai/providers/anthropic.rs b/backend/windmill-worker/src/ai/providers/anthropic.rs index 2bbfd83768..0a3c5df6e4 100644 --- a/backend/windmill-worker/src/ai/providers/anthropic.rs +++ b/backend/windmill-worker/src/ai/providers/anthropic.rs @@ -1,16 +1,16 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; -use windmill_ai::{ai_google::parse_data_url, ai_providers::AIProvider}; -use windmill_common::{client::AuthedClient, error::Error}; - -use crate::ai::{ +use windmill_ai::{ + ai_google::parse_data_url, + ai_providers::AIProvider, image_handler::prepare_messages_for_api, query_builder::{BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink}, sse::{AnthropicSSEParser, SSEParser}, types::*, utils::{extract_text_content, should_use_structured_output_tool}, }; +use windmill_common::{client::AuthedClient, error::Error}; /// Anthropic API version for standard API const ANTHROPIC_VERSION_STANDARD: &str = "2023-06-01"; diff --git a/backend/windmill-worker/src/ai/providers/bedrock.rs b/backend/windmill-worker/src/ai/providers/bedrock.rs index ce87d21a44..8c37433cab 100644 --- a/backend/windmill-worker/src/ai/providers/bedrock.rs +++ b/backend/windmill-worker/src/ai/providers/bedrock.rs @@ -6,25 +6,22 @@ //! - Stream event parsing //! - Helper utilities -use crate::ai::{ +use std::collections::HashMap; +use windmill_ai::{ image_handler::prepare_messages_for_api, query_builder::{ParsedResponse, StreamEventSink}, - types::StreamingEvent, - types::TokenUsage, - types::{OpenAIMessage, ToolDef}, + types::{OpenAIMessage, StreamingEvent, TokenUsage, ToolDef}, }; -use std::collections::HashMap; use windmill_common::{client::AuthedClient, error::Error}; -// Re-export from shared module for use by other parts of the worker +// Import shared Bedrock helpers for worker-specific orchestration. use windmill_ai::ai_bedrock::{ bedrock_model_supports_prompt_caching, bedrock_stream_event_is_block_stop, bedrock_stream_event_to_text, bedrock_stream_event_to_tool_delta, bedrock_stream_event_to_tool_start, build_tool_config, create_inference_config, format_bedrock_error, openai_messages_to_bedrock, streaming_tool_calls_to_openai, - StreamingToolCall, + BedrockClient, StreamingToolCall, }; -pub use windmill_ai::ai_bedrock::{check_env_credentials, BedrockClient}; // ============================================================================ // Query Builder (Worker-specific orchestration) diff --git a/backend/windmill-worker/src/ai/providers/google_ai.rs b/backend/windmill-worker/src/ai/providers/google_ai.rs index 6098cb22d8..19c50d06de 100644 --- a/backend/windmill-worker/src/ai/providers/google_ai.rs +++ b/backend/windmill-worker/src/ai/providers/google_ai.rs @@ -1,17 +1,16 @@ use async_trait::async_trait; -use windmill_ai::ai_google::{ - openai_messages_to_gemini, openai_tools_to_gemini, GeminiGenerationConfig, GeminiImageContent, - GeminiImageRequest, GeminiImageResponse, GeminiInlineData, GeminiPart, GeminiPredictContent, - GeminiTextRequest, GeminiTool, -}; -use windmill_common::{client::AuthedClient, error::Error}; - -use crate::ai::{ +use windmill_ai::{ + ai_google::{ + openai_messages_to_gemini, openai_tools_to_gemini, GeminiGenerationConfig, + GeminiImageContent, GeminiImageRequest, GeminiImageResponse, GeminiInlineData, GeminiPart, + GeminiPredictContent, GeminiTextRequest, GeminiTool, + }, image_handler::{download_and_encode_s3_image, prepare_messages_for_api}, query_builder::{BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink}, sse::{GeminiSSEParser, SSEParser}, types::*, }; +use windmill_common::{client::AuthedClient, error::Error}; // ============================================================================ // Query Builder Implementation diff --git a/backend/windmill-worker/src/ai/providers/openai.rs b/backend/windmill-worker/src/ai/providers/openai.rs index 52feb2eca7..e0767d5dda 100644 --- a/backend/windmill-worker/src/ai/providers/openai.rs +++ b/backend/windmill-worker/src/ai/providers/openai.rs @@ -1,17 +1,16 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; -use windmill_ai::ai_providers::AIProvider; -use windmill_ai::ai_types::OpenAIToolCall; -use windmill_common::{client::AuthedClient, error::Error}; - -use crate::ai::{ +use windmill_ai::{ + ai_providers::AIProvider, + ai_types::OpenAIToolCall, image_handler::{prepare_messages_for_api, s3_object_to_content_part}, query_builder::{BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink}, sse::{OpenAIResponsesSSEParser, SSEParser}, types::*, utils::extract_text_content, }; +use windmill_common::{client::AuthedClient, error::Error}; // Responses API structures #[derive(Deserialize)] diff --git a/backend/windmill-worker/src/ai/providers/openrouter.rs b/backend/windmill-worker/src/ai/providers/openrouter.rs index 68ad1922d3..ede541cd13 100644 --- a/backend/windmill-worker/src/ai/providers/openrouter.rs +++ b/backend/windmill-worker/src/ai/providers/openrouter.rs @@ -1,15 +1,15 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; use serde_json; -use windmill_ai::ai_providers::AIProvider; -use windmill_common::{client::AuthedClient, error::Error}; - -use crate::ai::{ +use windmill_ai::{ + ai_providers::AIProvider, image_handler::prepare_messages_for_api, - providers::other::OtherQueryBuilder, query_builder::{BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink}, types::*, }; +use windmill_common::{client::AuthedClient, error::Error}; + +use crate::ai::providers::other::OtherQueryBuilder; // OpenRouter-specific types #[derive(Serialize)] diff --git a/backend/windmill-worker/src/ai/providers/other.rs b/backend/windmill-worker/src/ai/providers/other.rs index f8ee60f287..a840517133 100644 --- a/backend/windmill-worker/src/ai/providers/other.rs +++ b/backend/windmill-worker/src/ai/providers/other.rs @@ -1,16 +1,15 @@ use async_trait::async_trait; use serde::Serialize; use serde_json; -use windmill_ai::ai_providers::AIProvider; -use windmill_common::{client::AuthedClient, error::Error}; - -use crate::ai::{ +use windmill_ai::{ + ai_providers::AIProvider, image_handler::prepare_messages_for_api, query_builder::{BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink}, sse::{OpenAISSEParser, SSEParser}, types::*, utils::should_use_structured_output_tool, }; +use windmill_common::{client::AuthedClient, error::Error}; #[derive(Serialize, Debug, Clone)] #[serde(rename_all = "lowercase")] diff --git a/backend/windmill-worker/src/ai/query_builder.rs b/backend/windmill-worker/src/ai/query_builder.rs index d74c45c098..606aa8f9db 100644 --- a/backend/windmill-worker/src/ai/query_builder.rs +++ b/backend/windmill-worker/src/ai/query_builder.rs @@ -1,24 +1,19 @@ use async_trait::async_trait; +use windmill_ai::{ + query_builder::{QueryBuilder, StreamEventSink}, + types::*, +}; use windmill_common::{error::Error, worker::Connection}; use windmill_queue::MiniPulledJob; use crate::{ - ai::{ - providers::{ - anthropic::AnthropicQueryBuilder, google_ai::GoogleAIQueryBuilder, - openai::OpenAIQueryBuilder, openrouter::OpenRouterQueryBuilder, - other::OtherQueryBuilder, - }, - types::*, + ai::providers::{ + anthropic::AnthropicQueryBuilder, google_ai::GoogleAIQueryBuilder, + openai::OpenAIQueryBuilder, openrouter::OpenRouterQueryBuilder, other::OtherQueryBuilder, }, job_logger::append_result_stream, }; -// Re-export from windmill_ai -pub use windmill_ai::query_builder::{ - BuildRequestArgs, ParsedResponse, QueryBuilder, StreamEventSink, -}; - /// Factory function to create the appropriate query builder for a provider pub fn create_query_builder(provider: &ProviderWithResource) -> Box { use windmill_ai::ai_providers::AIProvider; diff --git a/backend/windmill-worker/src/ai/tools.rs b/backend/windmill-worker/src/ai/tools.rs index c92fc2a94e..fcc9cdf3c9 100644 --- a/backend/windmill-worker/src/ai/tools.rs +++ b/backend/windmill-worker/src/ai/tools.rs @@ -1,6 +1,4 @@ -use crate::ai::query_builder::{StreamEventProcessor, StreamEventSink}; -use crate::ai::types::McpToolSource; -use crate::ai::types::*; +use crate::ai::query_builder::StreamEventProcessor; use crate::ai::utils::{ add_message_to_conversation, execute_mcp_tool, get_step_name_from_flow, is_completed_input_transform, update_flow_status_module_with_actions, @@ -20,7 +18,7 @@ use mappable_rc::Marc; use serde_json::value::RawValue; use std::{collections::HashMap, sync::Arc}; use uuid::Uuid; -use windmill_ai::ai_types::OpenAIToolCall; +use windmill_ai::{ai_types::OpenAIToolCall, query_builder::StreamEventSink, types::*}; use windmill_common::jobs::JobPayload; #[cfg(feature = "mcp")] diff --git a/backend/windmill-worker/src/ai/types.rs b/backend/windmill-worker/src/ai/types.rs deleted file mode 100644 index 57619f0dd9..0000000000 --- a/backend/windmill-worker/src/ai/types.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Re-export all types from windmill_ai::types -pub use windmill_ai::types::*; diff --git a/backend/windmill-worker/src/ai/utils.rs b/backend/windmill-worker/src/ai/utils.rs index f1e8fdd22f..74e75ef0a5 100644 --- a/backend/windmill-worker/src/ai/utils.rs +++ b/backend/windmill-worker/src/ai/utils.rs @@ -1,5 +1,3 @@ -pub use crate::ai::types::McpToolSource; -use crate::ai::types::ToolDef; use anyhow::Context; use serde_json::value::RawValue; use sqlx::types::Json; @@ -8,7 +6,7 @@ use std::{ sync::Arc, }; use uuid::Uuid; -use windmill_ai::ai_providers::AIProvider; +use windmill_ai::types::*; use windmill_common::flows::FlowModuleValue; use windmill_common::{ db::DB, @@ -24,7 +22,7 @@ use windmill_common::{ use windmill_mcp::{McpClient, McpResource, McpTool}; use windmill_queue::{flow_status::get_step_of_flow_status, MiniPulledJob}; -use crate::{ai::types::*, parse_sig_of_lang}; +use crate::parse_sig_of_lang; pub fn parse_raw_script_schema( content: &str, @@ -323,11 +321,6 @@ pub fn get_step_name_from_flow( ) } -/// AWS Bedrock do not handle structured output query param, so we use a tool for structured output. Same for every Claude models. -pub fn should_use_structured_output_tool(provider: &AIProvider, model: &str) -> bool { - model.contains("claude") || provider == &AIProvider::AWSBedrock -} - /// Cleanup MCP clients by gracefully shutting down connections #[cfg(feature = "mcp")] pub async fn cleanup_mcp_clients(mcp_clients: HashMap>) { @@ -713,21 +706,3 @@ pub fn any_tool_needs_previous_result(tools: &[Tool]) -> bool { false }) } - -/// Extract text content from OpenAIContent, joining parts with space if multiple -pub fn extract_text_content(content: &OpenAIContent) -> String { - match content { - OpenAIContent::Text(text) => text.clone(), - OpenAIContent::Parts(parts) => parts - .iter() - .filter_map(|p| { - if let ContentPart::Text { text } = p { - Some(text.as_str()) - } else { - None - } - }) - .collect::>() - .join(""), - } -} diff --git a/backend/windmill-worker/src/ai_executor.rs b/backend/windmill-worker/src/ai_executor.rs index 03153df0a4..cdf2995f9c 100644 --- a/backend/windmill-worker/src/ai_executor.rs +++ b/backend/windmill-worker/src/ai_executor.rs @@ -1,12 +1,10 @@ -#[cfg(feature = "bedrock")] -use crate::ai::providers::bedrock::check_env_credentials; use crate::ai::tools::{execute_tool_calls, ToolAbortHandles, ToolExecutionContext}; use crate::ai::utils::{ add_message_to_conversation, any_tool_needs_previous_result, cleanup_mcp_clients, filter_schema_by_input_transforms, find_unique_tool_name, get_flow_context, get_flow_job_runnable_and_raw_flow, get_step_name_from_flow, load_mcp_tools, - parse_raw_script_schema, should_use_structured_output_tool, - update_flow_status_module_with_actions, update_flow_status_module_with_actions_success, + parse_raw_script_schema, update_flow_status_module_with_actions, + update_flow_status_module_with_actions_success, }; use crate::memory_oss::{read_from_memory, write_to_memory}; use crate::worker_flow::{get_previous_job_result, get_transform_context}; @@ -15,12 +13,20 @@ use regex::Regex; use serde_json::value::RawValue; use std::{collections::HashMap, sync::Arc}; use uuid::Uuid; +#[cfg(feature = "bedrock")] +use windmill_ai::ai_bedrock::check_env_credentials; #[cfg(feature = "mcp")] use windmill_mcp::McpClient; #[cfg(not(feature = "mcp"))] use crate::ai::tools::McpClientStub as McpClient; -use windmill_ai::ai_providers::AIProvider; +use windmill_ai::{ + ai_providers::AIProvider, + image_handler::upload_image_to_s3, + query_builder::{BuildRequestArgs, ParsedResponse}, + types::*, + utils::{should_use_structured_output_tool, AI_HTTP_HEADERS}, +}; use windmill_common::{ cache, client::AuthedClient, @@ -38,13 +44,7 @@ use windmill_common::{ use windmill_queue::{cancel_single_job, CanceledBy, MiniPulledJob}; use crate::{ - ai::{ - image_handler::upload_image_to_s3, - query_builder::{ - create_query_builder, BuildRequestArgs, ParsedResponse, StreamEventProcessor, - }, - types::*, - }, + ai::query_builder::{create_query_builder, StreamEventProcessor}, common::{build_args_map, resolve_job_timeout, OccupancyMetrics, StreamNotifier}, handle_child::{run_future_with_polling_update_job_poller_graceful, GracefulPollOutcome}, }; @@ -52,33 +52,6 @@ use crate::{ lazy_static::lazy_static! { static ref TOOL_NAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_]+$").unwrap(); - /// Parse AI_HTTP_HEADERS environment variable into a vector of (header_name, header_value) tuples - /// Format: "header1: value1, header2: value2" - static ref AI_HTTP_HEADERS: Vec<(String, String)> = { - std::env::var("AI_HTTP_HEADERS") - .ok() - .map(|headers_str| { - headers_str - .split(',') - .filter_map(|header| { - let parts: Vec<&str> = header.splitn(2, ':').collect(); - if parts.len() == 2 { - let name = parts[0].trim().to_string(); - let value = parts[1].trim().to_string(); - if !name.is_empty() && !value.is_empty() { - Some((name, value)) - } else { - None - } - } else { - None - } - }) - .collect() - }) - .unwrap_or_default() - }; - static ref AI_AGENT_TOOL_SCHEMA: Box = to_raw_value(&serde_json::json!({ "type": "object", "properties": { @@ -791,7 +764,7 @@ pub async fn run_agent( let mut actions = vec![]; let mut content = None; - let mut final_usage: Option = None; + let mut final_usage: Option = None; // Check if this provider supports tools with the current output type let supports_tools = query_builder.supports_tools_with_output_type(output_type); @@ -1231,7 +1204,8 @@ pub async fn run_agent( } ParsedResponse::Image { base64_data } => { // For image output, upload to S3 and track in conversation - let s3_object = upload_image_to_s3(&base64_data, job, client).await?; + let s3_object = + upload_image_to_s3(&base64_data, &job.workspace_id, &job.id, client).await?; let content = to_raw_value(&s3_object); diff --git a/backend/windmill-worker/src/memory_common.rs b/backend/windmill-worker/src/memory_common.rs index 440199702f..e024acea69 100644 --- a/backend/windmill-worker/src/memory_common.rs +++ b/backend/windmill-worker/src/memory_common.rs @@ -1,5 +1,5 @@ -use crate::ai::types::OpenAIMessage; use uuid::Uuid; +use windmill_ai::types::OpenAIMessage; use windmill_common::{db::DB, error::Error}; pub const MAX_MEMORY_SIZE_BYTES: usize = 100_000; // 100KB per memory entry in database diff --git a/backend/windmill-worker/src/memory_oss.rs b/backend/windmill-worker/src/memory_oss.rs index 74771a79e8..dcdab14e2a 100644 --- a/backend/windmill-worker/src/memory_oss.rs +++ b/backend/windmill-worker/src/memory_oss.rs @@ -3,7 +3,9 @@ pub use crate::memory_ee::*; #[cfg(not(all(feature = "private", feature = "enterprise")))] -use {crate::ai::types::OpenAIMessage, crate::memory_common, uuid::Uuid, windmill_common::db::DB}; +use { + crate::memory_common, uuid::Uuid, windmill_ai::types::OpenAIMessage, windmill_common::db::DB, +}; /// Read AI agent memory from storage /// In OSS: always reads from database diff --git a/cli/src/guidance/skills.gen.ts b/cli/src/guidance/skills.gen.ts index 72d2e9d76b..656f24e5a9 100644 --- a/cli/src/guidance/skills.gen.ts +++ b/cli/src/guidance/skills.gen.ts @@ -5420,7 +5420,7 @@ Reference a specific resource using \`$res:\` prefix: ## OpenFlow Schema -{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/-"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`, +{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/-"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"},"max_iterations":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Number. Limits how many times the agent can loop through reasoning and tool use.\\nRange: 1-1000.\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`, "raw-app": `--- name: raw-app description: MUST use when creating raw apps. diff --git a/docs/windmill-ai-refactor-plan.md b/docs/windmill-ai-refactor-plan.md index 81ab5d7b86..78b82ddcc6 100644 --- a/docs/windmill-ai-refactor-plan.md +++ b/docs/windmill-ai-refactor-plan.md @@ -23,6 +23,58 @@ windmill-worker → windmill-ai windmill-common does **NOT** re-export from windmill-ai (would be circular). All consumers update imports. +## Reviewer Note: Keep the Next PR Small + +The first merged PR established the crate boundary; it did not yet remove the duplicated API-vs-worker provider paths. The remaining work should stay split by dependency risk, not by the final desired module layout. + +Do not jump directly from the current state to provider moves, proxy unification, and credential unification in one PR. The riskiest part is the API proxy because it combines request transformation, endpoint selection, auth headers, custom headers, OAuth user injection, Azure URL handling, Anthropic Vertex handling, Bedrock SDK calls, and SSE keepalive behavior. + +Pull the shared plumbing forward before moving provider implementations: +- Move tiny shared utilities first, including `AI_HTTP_HEADERS`, `extract_text_content`, and `should_use_structured_output_tool`. +- Move SSE parsers next, using the existing `StreamEventSink` abstraction, and update callers to import from `windmill_ai` directly. +- Leave provider implementations, image upload/download handling, API proxy changes, and credential unification out of that PR. + +Avoid adding modules whose only purpose is to re-export moved code. Direct imports from `windmill_ai` make ownership and dependency direction clearer at each call site. + +Also do not make `build_proxy_request(raw_body, path)` too narrow. The proxy path needs method, incoming headers, resolved credentials, base URL/platform, organization/user fields, custom headers, and Bedrock/Azure/Vertex-specific context. Introduce a structured `ProxyBuildArgs`/`ProviderCredentials` shape before deleting `AIRequestConfig::prepare_request`, `google.rs`, or `bedrock.rs`. + +## Next Phase PR: Shared Plumbing Only + +Goal: make `windmill-ai` own the provider-independent helper code that later provider moves will need, without changing API proxy behavior or agent request behavior. + +Suggested PR title: `refactor(ai): move shared SSE plumbing into windmill-ai`. + +Scope: +- Add `windmill-ai/src/utils.rs`. +- Move the duplicated `AI_HTTP_HEADERS` parsing into `windmill_ai::utils` with identical parsing behavior. +- Move `extract_text_content` and `should_use_structured_output_tool` from `windmill-worker/src/ai/utils.rs` to `windmill_ai::utils`. +- Move `windmill-worker/src/ai/sse.rs` to `windmill-ai/src/sse.rs`. +- Delete `windmill-worker/src/ai/sse.rs` and update callers to import parser types from `windmill_ai::sse`. +- Update callers of moved utility functions to import from `windmill_ai::utils` directly. +- Add the minimal new `windmill-ai` dependencies required by `sse.rs` (`eventsource-stream`, `tokio-stream`) and avoid adding worker/queue dependencies. + +Out of scope: +- Do not move provider implementations. +- Do not move `image_handler`. +- Do not change `QueryBuilder` method signatures. +- Do not add `build_proxy_request`. +- Do not change API proxy routing, request preparation, credential resolution, audit logging, cache behavior, or Bedrock/Google special cases. +- Do not remove `windmill-api/src/google.rs`, `windmill-api/src/bedrock.rs`, or `AIRequestConfig::prepare_request`. + +Implementation checklist: +1. Add `utils.rs` to `windmill-ai` and export it from `lib.rs`. +2. Move `AI_HTTP_HEADERS` exactly once, then update `windmill-api/src/ai.rs` and `windmill-worker/src/ai_executor.rs` to import it. +3. Move the two provider-independent helper functions into `windmill_ai::utils`; leave worker-specific flow/MCP/conversation utilities in `windmill-worker/src/ai/utils.rs`. +4. Move `sse.rs` into `windmill-ai`, change imports from `crate::ai::{query_builder, types}` to `crate::{query_builder, types}`, and keep behavior unchanged. +5. Remove worker `ai/sse.rs` and update provider imports to use `windmill_ai::sse` directly. +6. Run focused grep checks for duplicate `AI_HTTP_HEADERS`, old local helper definitions, and accidental `windmill_queue`/worker dependencies from `windmill-ai`. +7. Validate with `cargo check -p windmill-ai`, `cargo check -p windmill-worker`, and `cargo check -p windmill-api`. For `bedrock` builds, also check the existing bedrock feature path. + +Review expectations: +- The diff should be mostly moved code and import updates. +- The behavior should be byte-for-byte equivalent where practical. +- Tests are only needed if helper behavior changes. For a pure move, existing backend checks plus manual AI streaming verification are enough. + ## Step-by-Step Plan Each step produces a compiling, working backend. @@ -131,18 +183,27 @@ This is the key unification step. Add a new method to the `QueryBuilder` trait: /// Used by the API chat proxy. Handles format conversion for non-OpenAI providers. fn build_proxy_request( &self, - raw_body: &[u8], - path: &str, + args: &ProxyBuildArgs<'_>, ) -> Result; ``` -Where `ProxyRequest` contains the transformed body, endpoint URL, and auth headers: +Where `ProxyBuildArgs` carries the API proxy context that provider implementations need: +```rust +pub struct ProxyBuildArgs<'a> { + pub method: http::Method, + pub path: &'a str, + pub headers: &'a http::HeaderMap, + pub body: &'a [u8], + pub credentials: &'a ProviderCredentials, +} +``` + +And `ProxyRequest` contains the transformed request: ```rust pub struct ProxyRequest { pub url: String, pub body: Vec, - pub auth_headers: Vec<(String, String)>, - pub is_sse: bool, + pub headers: Vec<(String, String)>, } ``` @@ -153,9 +214,9 @@ pub struct ProxyRequest { - **Bedrock**: Convert OpenAI format → Bedrock SDK calls. Replaces `windmill-api/src/bedrock.rs`. **Refactor API proxy** (`windmill-api/src/ai.rs`): -1. Parse provider from headers, resolve credentials → `ProviderWithResource` +1. Parse provider from headers, resolve credentials → `ProviderCredentials` 2. Create `QueryBuilder` via `create_query_builder` -3. Call `query_builder.build_proxy_request(body, path)` → `ProxyRequest` +3. Call `query_builder.build_proxy_request(&proxy_args)` → `ProxyRequest` 4. Send the request, return response with SSE keepalive injection **Remove** from windmill-api: @@ -166,7 +227,7 @@ pub struct ProxyRequest { - `supports_native_fim`, `transform_fim_to_chat_completions` — moved to windmill-ai **Keep** in API: -- `AIRequestConfig::new` credential resolution (or refactor to produce `ProviderWithResource`) +- `AIRequestConfig::new` credential resolution until it is refactored to produce `ProviderCredentials` - HTTP routes, audit logging, request caching - `inject_keepalives`, `is_sse_response` helpers - `AIConfig`, `ExpiringAIRequestConfig` caching types diff --git a/flake.nix b/flake.nix index aaf06c882e..3872ee636f 100644 --- a/flake.nix +++ b/flake.nix @@ -79,11 +79,11 @@ # --------------------------------------------------------------- rustyV8Archive = let - version = "130.0.7"; + version = "137.1.0"; target = stdenv.hostPlatform.rust.rustcTarget; sha256 = { x86_64-linux = - "sha256-pkdsuU6bAkcIHEZUJOt5PXdzK424CEgTLXjLtQ80t10="; + "sha256-Tiscfy2bzYGR3s0T+SC1IB3xWvTVpVcSEdjq3MCRoRw="; aarch64-linux = lib.fakeHash; x86_64-darwin = lib.fakeHash; aarch64-darwin = lib.fakeHash; diff --git a/frontend/src/lib/components/Auth0Setting.svelte b/frontend/src/lib/components/Auth0Setting.svelte index beb9ec03f9..a246ae196d 100644 --- a/frontend/src/lib/components/Auth0Setting.svelte +++ b/frontend/src/lib/components/Auth0Setting.svelte @@ -7,6 +7,7 @@ import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte' import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte' import TextInput from './text_input/TextInput.svelte' + import Password from './Password.svelte' import SettingCard from './instanceSettings/SettingCard.svelte' interface Props { @@ -103,14 +104,15 @@ class="max-w-lg" /> - - -