From c1351f815531480083f6d58dbbfb9290dfd26ef2 Mon Sep 17 00:00:00 2001 From: dieriba Date: Tue, 18 Feb 2025 23:49:45 +0100 Subject: [PATCH] feat: SQS triggers (#5182) * feat: first commit * fix: npm check * fix: openapi file * feat: update openapi and migration * feat: basic implementation done * fix: fix: no used function when no feature * feat: capture done * Update capture.rs * nits: change sqs trigger * fix: make migration great again * feat: add message attributes * feat: nits: fix error messages, remove console.log and add try catch * update sqs icon and ee feature for sqs_trigger * update: change sqs name casing and added test connection button * nits: update Icon and add create from template button * fix: ci build and error compilation * update migration type sqs * update link on create from template button for sqs, add archive in workspace export and update sqlx * fix: ci * Update SqsTriggerEditorInner.svelte * add link to docs, use generic function for resource and fix import error * chore: update .github ci * nits: remove empty * update to match ee repo changement * Update backend/windmill-api/src/resources.rs Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * add sqs handling for the cli and refacoring sqsEditorInner * Update cli/sync.ts Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * fix: add break to switch statement for sqs case * fix: display aws_resource_path when retrieve or create a new trigger * rework sqs ui, fix postgres optional port * fix: ci * update ui for trigger * update repo ref and specific * feat: add ready endpoints for workers to enterprise * update ref * Update frontend/src/lib/script_helpers.ts Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --------- Co-authored-by: HugoCasa Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> Co-authored-by: Ruben Fiszel --- .github/workflows/build-publish-rh-image.yml | 4 +- .github/workflows/build_windows_worker_.yml | 2 +- .github/workflows/docker-image.yml | 2 +- .github/workflows/publish_windows_worker.yml | 2 +- ...254c783fc34b617c8a9a95a0eb0cda535dab5.json | 3 +- ...9418f85d4d3d599f4177403fad5ad99380715.json | 26 ++ ...d982b52b48c8c3da392b14963a1ec86811546.json | 50 +++ ...f8b0672797299545ee0754b6ad74ece92c77e.json | 26 ++ ...c776994ae2c990bb7bb307c52296b9543fbb8.json | 16 + ...27bcf833f56475bbc1aa3c8f6d79f146f41bf.json | 25 ++ ...082b00c44fd4a7e98a11b714133674a7b6da7.json | 106 +++++ ...93de351653ab9ac171fa0eea447c905440867.json | 107 +++++ ...287a9f42e252a1246a584249a224afdbbbf8a.json | 16 + ...41d95ba195f5543120e76e68f6e6715b65a71.json | 24 + ...64c5a91e3ed8d9260c72b783fc12542b88fbd.json | 6 +- ...daf5d4205d160d2aedf463c7dfe944e93257a.json | 3 +- ...cabb01481a19bef5a956dc36cac41acad0e53.json | 25 ++ ...451217ccb9f1bc35b1ad6e10d16bc19c41447.json | 3 +- ...ef9f4c8faa986843024a2cd58e212f706aae8.json | 17 + ...8e5fdaff0e601e2760cc5653d197c51b106bb.json | 52 +++ ...a8e119bffd2982b97fc900358506a0a14bbb8.json | 23 + ...f3490f88ced636c9ebdecba2205f964b1d0f1.json | 15 + ...23b4376a93342702856da2ac70f6bbfc7933e.json | 23 + ...677774aa237508d5610714efd2e9b8b93c7b8.json | 3 +- ...0da43239c9a5aaea41c9aed7ed33a6219a534.json | 3 +- ...05d394a7cbcf0038c72a78add5c7b02ef5927.json | 2 +- ...33ba30fa85efcc83fafe4dd7b4e535b96a8d8.json | 15 + ...fdda86bee33f31835317df512a20c805b35d7.json | 3 +- ...0e7bc1f0dbeca2e4f44ced05bae0ca5ca1039.json | 3 +- ...23c94caae2421f3cae7c06d6346bd6de1d94a.json | 104 +++++ ...2777e04e4965682e5b37afbe84194b756d5f5.json | 23 + backend/.vscode/settings.json | 2 +- backend/Cargo.lock | 24 + backend/Cargo.toml | 2 + backend/ee-repo-ref.txt | 2 +- .../20250130184358_sqs_trigger.down.sql | 2 + .../20250130184358_sqs_trigger.up.sql | 69 +++ ...s_type_value_to_trigger_kind_type.down.sql | 1 + ...sqs_type_value_to_trigger_kind_type.up.sql | 2 + backend/src/main.rs | 1 + backend/windmill-api/Cargo.toml | 5 +- backend/windmill-api/openapi.yaml | 386 ++++++++++++---- backend/windmill-api/src/capture.rs | 12 + backend/windmill-api/src/kafka_triggers_ee.rs | 2 +- backend/windmill-api/src/lib.rs | 82 ++-- backend/windmill-api/src/nats_triggers_ee.rs | 2 +- .../src/postgres_triggers/handler.rs | 9 +- .../windmill-api/src/postgres_triggers/mod.rs | 65 +-- .../src/postgres_triggers/trigger.rs | 14 +- backend/windmill-api/src/resources.rs | 45 +- backend/windmill-api/src/sqs_triggers_ee.rs | 31 ++ backend/windmill-api/src/variables.rs | 2 +- backend/windmill-api/src/workspaces.rs | 4 +- backend/windmill-api/src/workspaces_export.rs | 22 + backend/windmill-common/src/variables.rs | 1 + cli/gen/core/OpenAPI.ts | 2 +- cli/gen/services.gen.ts | 174 +++++++- cli/gen/types.gen.ts | 177 ++++++-- cli/sync.ts | 12 +- cli/trigger.ts | 11 +- cli/types.ts | 4 + frontend/src/lib/components/Path.svelte | 9 +- frontend/src/lib/components/ShareModal.svelte | 1 + .../details/DetailPageDetailPanel.svelte | 4 +- .../details/DetailPageLayout.svelte | 7 +- .../details/DetailPageTriggerPanel.svelte | 15 +- .../renderers/triggers/TriggersBadge.svelte | 9 +- .../src/lib/components/icons/AwsIcon.svelte | 31 +- .../components/sidebar/OperatorMenu.svelte | 5 + .../components/sidebar/SidebarContent.svelte | 8 + frontend/src/lib/components/triggers.ts | 3 + .../components/triggers/CaptureButton.svelte | 10 + .../components/triggers/CaptureWrapper.svelte | 26 +- .../triggers/TestTriggerConnection.svelte | 9 +- .../components/triggers/TriggersEditor.svelte | 26 +- .../triggers/TriggersEditorSection.svelte | 1 + .../triggers/TriggersWrapper.svelte | 10 + .../http/RouteEditorConfigSection.svelte | 38 +- .../triggers/http/RouteEditorInner.svelte | 20 +- .../kafka/KafkaTriggerEditorInner.svelte | 14 +- .../nats/NatsTriggerEditorInner.svelte | 15 +- .../PostgresEditorConfigSection.svelte | 2 +- .../PostgresTriggerEditorInner.svelte | 4 +- .../triggers/postgres/RelationPicker.svelte | 46 +- .../triggers/sqs/SqsTriggerEditor.svelte | 27 ++ .../sqs/SqsTriggerEditorConfigSection.svelte | 152 +++++++ .../triggers/sqs/SqsTriggerEditorInner.svelte | 241 ++++++++++ .../triggers/sqs/SqsTriggerPanel.svelte | 135 ++++++ .../WebsocketEditorConfigSection.svelte | 42 +- .../WebsocketTriggerEditorInner.svelte | 16 +- frontend/src/lib/script_helpers.ts | 209 +++++---- .../src/routes/(root)/(logged)/+layout.svelte | 13 +- .../(logged)/flows/get/[...path]/+page.svelte | 8 + .../scripts/get/[...hash]/+page.svelte | 16 +- .../(root)/(logged)/sqs_triggers/+page.js | 5 + .../(root)/(logged)/sqs_triggers/+page.svelte | 422 ++++++++++++++++++ 96 files changed, 3037 insertions(+), 461 deletions(-) create mode 100644 backend/.sqlx/query-1625a84fbcf8c5f77eb0519f60d9418f85d4d3d599f4177403fad5ad99380715.json create mode 100644 backend/.sqlx/query-1b33393fbbc7e681b4d355f6096d982b52b48c8c3da392b14963a1ec86811546.json create mode 100644 backend/.sqlx/query-1cad25c24d0f80d58a50d4da923f8b0672797299545ee0754b6ad74ece92c77e.json create mode 100644 backend/.sqlx/query-20e01ecb5d4aa4c532a8f906365c776994ae2c990bb7bb307c52296b9543fbb8.json create mode 100644 backend/.sqlx/query-22dcd953d900fb0ddbe2099ccee27bcf833f56475bbc1aa3c8f6d79f146f41bf.json create mode 100644 backend/.sqlx/query-2b6c13191484b0c664f35e2c811082b00c44fd4a7e98a11b714133674a7b6da7.json create mode 100644 backend/.sqlx/query-2ef82fad8a6ccdc66228cfbce5393de351653ab9ac171fa0eea447c905440867.json create mode 100644 backend/.sqlx/query-3f67e7cf8d9f021a075f1c88703287a9f42e252a1246a584249a224afdbbbf8a.json create mode 100644 backend/.sqlx/query-5bd8ae8d694ac9f6afef762276141d95ba195f5543120e76e68f6e6715b65a71.json create mode 100644 backend/.sqlx/query-6b776693091191f36eaf9e35fb3cabb01481a19bef5a956dc36cac41acad0e53.json create mode 100644 backend/.sqlx/query-7e31c47e02492b74cbb5702dfc5ef9f4c8faa986843024a2cd58e212f706aae8.json create mode 100644 backend/.sqlx/query-93d0ee34c7b7c56ab9cae28071f8e5fdaff0e601e2760cc5653d197c51b106bb.json create mode 100644 backend/.sqlx/query-9b9bc21023f10a0b4bb45879c7da8e119bffd2982b97fc900358506a0a14bbb8.json create mode 100644 backend/.sqlx/query-a5fbef9db2308920ea26f6154f0f3490f88ced636c9ebdecba2205f964b1d0f1.json create mode 100644 backend/.sqlx/query-b386d320f9fe1d569a16e6626b723b4376a93342702856da2ac70f6bbfc7933e.json create mode 100644 backend/.sqlx/query-dea056c89313f4facd62cbbc9fa33ba30fa85efcc83fafe4dd7b4e535b96a8d8.json create mode 100644 backend/.sqlx/query-e6adaebcade2e25be800e8b888b23c94caae2421f3cae7c06d6346bd6de1d94a.json create mode 100644 backend/.sqlx/query-f68d23841e0e31cdf8633aaf0f32777e04e4965682e5b37afbe84194b756d5f5.json create mode 100644 backend/migrations/20250130184358_sqs_trigger.down.sql create mode 100644 backend/migrations/20250130184358_sqs_trigger.up.sql create mode 100644 backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.down.sql create mode 100644 backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.up.sql create mode 100644 backend/windmill-api/src/sqs_triggers_ee.rs create mode 100644 frontend/src/lib/components/triggers/sqs/SqsTriggerEditor.svelte create mode 100644 frontend/src/lib/components/triggers/sqs/SqsTriggerEditorConfigSection.svelte create mode 100644 frontend/src/lib/components/triggers/sqs/SqsTriggerEditorInner.svelte create mode 100644 frontend/src/lib/components/triggers/sqs/SqsTriggerPanel.svelte create mode 100644 frontend/src/routes/(root)/(logged)/sqs_triggers/+page.js create mode 100644 frontend/src/routes/(root)/(logged)/sqs_triggers/+page.svelte diff --git a/.github/workflows/build-publish-rh-image.yml b/.github/workflows/build-publish-rh-image.yml index 060f572fe8..88154da3db 100644 --- a/.github/workflows/build-publish-rh-image.yml +++ b/.github/workflows/build-publish-rh-image.yml @@ -64,7 +64,7 @@ jobs: platforms: linux/amd64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,sqs_trigger,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust secrets: | rh_username=${{ secrets.RH_USERNAME }} rh_password=${{ secrets.RH_PASSWORD }} @@ -81,7 +81,7 @@ jobs: platforms: linux/arm64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,sqs_trigger,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust secrets: | rh_username=${{ secrets.RH_USERNAME }} rh_password=${{ secrets.RH_PASSWORD }} diff --git a/.github/workflows/build_windows_worker_.yml b/.github/workflows/build_windows_worker_.yml index 6082a47e9b..8657bfca6b 100644 --- a/.github/workflows/build_windows_worker_.yml +++ b/.github/workflows/build_windows_worker_.yml @@ -45,7 +45,7 @@ jobs: $env:OPENSSL_DIR="${Env:VCPKG_INSTALLATION_ROOT}\installed\x64-windows-static" mkdir frontend/build && cd backend New-Item -Path . -Name "windmill-api/openapi-deref.yaml" -ItemType "File" -Force - cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust + cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,sqs_trigger,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust - name: Rename binary with corresponding architecture run: | diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 18145886db..3d5add18c0 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -158,7 +158,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,otel,dind,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,sqs_trigger,nats,otel,dind,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }} ${{ steps.meta-ee-public.outputs.tags }} diff --git a/.github/workflows/publish_windows_worker.yml b/.github/workflows/publish_windows_worker.yml index b97d3b5560..b4b03a99e2 100644 --- a/.github/workflows/publish_windows_worker.yml +++ b/.github/workflows/publish_windows_worker.yml @@ -47,7 +47,7 @@ jobs: $env:OPENSSL_DIR="${Env:VCPKG_INSTALLATION_ROOT}\installed\x64-windows-static" mkdir frontend/build && cd backend New-Item -Path . -Name "windmill-api/openapi-deref.yaml" -ItemType "File" -Force - cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust + cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,sqs_trigger,nats,php,mysql,mssql,bigquery,oracledb,postgres_trigger,websocket,python,smtp,csharp,static_frontend,rust - name: Rename binary with corresponding architecture run: | diff --git a/backend/.sqlx/query-07da723ce5c9ee2d7c236e8eabe254c783fc34b617c8a9a95a0eb0cda535dab5.json b/backend/.sqlx/query-07da723ce5c9ee2d7c236e8eabe254c783fc34b617c8a9a95a0eb0cda535dab5.json index f7685bf7eb..6eacfceb62 100644 --- a/backend/.sqlx/query-07da723ce5c9ee2d7c236e8eabe254c783fc34b617c8a9a95a0eb0cda535dab5.json +++ b/backend/.sqlx/query-07da723ce5c9ee2d7c236e8eabe254c783fc34b617c8a9a95a0eb0cda535dab5.json @@ -19,7 +19,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-1625a84fbcf8c5f77eb0519f60d9418f85d4d3d599f4177403fad5ad99380715.json b/backend/.sqlx/query-1625a84fbcf8c5f77eb0519f60d9418f85d4d3d599f4177403fad5ad99380715.json new file mode 100644 index 0000000000..f0ee89dbc9 --- /dev/null +++ b/backend/.sqlx/query-1625a84fbcf8c5f77eb0519f60d9418f85d4d3d599f4177403fad5ad99380715.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger \n SET \n enabled = $1, \n email = $2, \n edited_by = $3, \n edited_at = now(), \n server_id = NULL, \n error = NULL\n WHERE \n path = $4 AND \n workspace_id = $5 \n RETURNING 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Bool", + "Varchar", + "Varchar", + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "1625a84fbcf8c5f77eb0519f60d9418f85d4d3d599f4177403fad5ad99380715" +} diff --git a/backend/.sqlx/query-1b33393fbbc7e681b4d355f6096d982b52b48c8c3da392b14963a1ec86811546.json b/backend/.sqlx/query-1b33393fbbc7e681b4d355f6096d982b52b48c8c3da392b14963a1ec86811546.json new file mode 100644 index 0000000000..271c60b480 --- /dev/null +++ b/backend/.sqlx/query-1b33393fbbc7e681b4d355f6096d982b52b48c8c3da392b14963a1ec86811546.json @@ -0,0 +1,50 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n path,\n is_flow,\n workspace_id,\n owner,\n email,\n trigger_config as \"trigger_config!: _\"\n FROM\n capture_config\n WHERE\n trigger_kind = 'sqs' AND\n last_client_ping > NOW() - INTERVAL '10 seconds' AND\n trigger_config IS NOT NULL AND\n (last_server_ping IS NULL OR last_server_ping < now() - interval '15 seconds')\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "is_flow", + "type_info": "Bool" + }, + { + "ordinal": 2, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "owner", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "email", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "trigger_config!: _", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + false, + false, + false, + true + ] + }, + "hash": "1b33393fbbc7e681b4d355f6096d982b52b48c8c3da392b14963a1ec86811546" +} diff --git a/backend/.sqlx/query-1cad25c24d0f80d58a50d4da923f8b0672797299545ee0754b6ad74ece92c77e.json b/backend/.sqlx/query-1cad25c24d0f80d58a50d4da923f8b0672797299545ee0754b6ad74ece92c77e.json new file mode 100644 index 0000000000..0729adc8ba --- /dev/null +++ b/backend/.sqlx/query-1cad25c24d0f80d58a50d4da923f8b0672797299545ee0754b6ad74ece92c77e.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n capture_config \n SET \n last_server_ping = now(), \n error = $1 \n WHERE \n workspace_id = $2 AND \n path = $3 AND \n is_flow = $4 AND \n trigger_kind = 'sqs' AND \n server_id = $5 AND \n last_client_ping > NOW() - INTERVAL '10 seconds' \n RETURNING 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Bool", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "1cad25c24d0f80d58a50d4da923f8b0672797299545ee0754b6ad74ece92c77e" +} diff --git a/backend/.sqlx/query-20e01ecb5d4aa4c532a8f906365c776994ae2c990bb7bb307c52296b9543fbb8.json b/backend/.sqlx/query-20e01ecb5d4aa4c532a8f906365c776994ae2c990bb7bb307c52296b9543fbb8.json new file mode 100644 index 0000000000..c9f7733011 --- /dev/null +++ b/backend/.sqlx/query-20e01ecb5d4aa4c532a8f906365c776994ae2c990bb7bb307c52296b9543fbb8.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE \n capture_config \n SET \n last_server_ping = NULL \n WHERE \n workspace_id = $1 AND \n path = $2 AND \n is_flow = $3 AND \n trigger_kind = 'sqs' AND \n server_id IS NULL\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Bool" + ] + }, + "nullable": [] + }, + "hash": "20e01ecb5d4aa4c532a8f906365c776994ae2c990bb7bb307c52296b9543fbb8" +} diff --git a/backend/.sqlx/query-22dcd953d900fb0ddbe2099ccee27bcf833f56475bbc1aa3c8f6d79f146f41bf.json b/backend/.sqlx/query-22dcd953d900fb0ddbe2099ccee27bcf833f56475bbc1aa3c8f6d79f146f41bf.json new file mode 100644 index 0000000000..f94ca24f0f --- /dev/null +++ b/backend/.sqlx/query-22dcd953d900fb0ddbe2099ccee27bcf833f56475bbc1aa3c8f6d79f146f41bf.json @@ -0,0 +1,25 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger\n SET \n last_server_ping = now(),\n error = $1\n WHERE\n workspace_id = $2\n AND path = $3\n AND server_id = $4 \n AND enabled IS TRUE\n RETURNING 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "22dcd953d900fb0ddbe2099ccee27bcf833f56475bbc1aa3c8f6d79f146f41bf" +} diff --git a/backend/.sqlx/query-2b6c13191484b0c664f35e2c811082b00c44fd4a7e98a11b714133674a7b6da7.json b/backend/.sqlx/query-2b6c13191484b0c664f35e2c811082b00c44fd4a7e98a11b714133674a7b6da7.json new file mode 100644 index 0000000000..be9f392048 --- /dev/null +++ b/backend/.sqlx/query-2b6c13191484b0c664f35e2c811082b00c44fd4a7e98a11b714133674a7b6da7.json @@ -0,0 +1,106 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT * FROM sqs_trigger\n WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "queue_url", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "aws_resource_path", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "message_attributes", + "type_info": "TextArray" + }, + { + "ordinal": 4, + "name": "script_path", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "is_flow", + "type_info": "Bool" + }, + { + "ordinal": 6, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 7, + "name": "edited_by", + "type_info": "Varchar" + }, + { + "ordinal": 8, + "name": "email", + "type_info": "Varchar" + }, + { + "ordinal": 9, + "name": "edited_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 10, + "name": "extra_perms", + "type_info": "Jsonb" + }, + { + "ordinal": 11, + "name": "error", + "type_info": "Text" + }, + { + "ordinal": 12, + "name": "server_id", + "type_info": "Varchar" + }, + { + "ordinal": 13, + "name": "last_server_ping", + "type_info": "Timestamptz" + }, + { + "ordinal": 14, + "name": "enabled", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false, + true, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false + ] + }, + "hash": "2b6c13191484b0c664f35e2c811082b00c44fd4a7e98a11b714133674a7b6da7" +} diff --git a/backend/.sqlx/query-2ef82fad8a6ccdc66228cfbce5393de351653ab9ac171fa0eea447c905440867.json b/backend/.sqlx/query-2ef82fad8a6ccdc66228cfbce5393de351653ab9ac171fa0eea447c905440867.json new file mode 100644 index 0000000000..5d1af3380d --- /dev/null +++ b/backend/.sqlx/query-2ef82fad8a6ccdc66228cfbce5393de351653ab9ac171fa0eea447c905440867.json @@ -0,0 +1,107 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n aws_resource_path,\n message_attributes,\n queue_url,\n workspace_id,\n path,\n script_path,\n is_flow,\n edited_by,\n email,\n edited_at,\n server_id,\n last_server_ping,\n extra_perms,\n error,\n enabled\n FROM \n sqs_trigger\n WHERE \n workspace_id = $1 AND \n path = $2\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "aws_resource_path", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "message_attributes", + "type_info": "TextArray" + }, + { + "ordinal": 2, + "name": "queue_url", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "script_path", + "type_info": "Varchar" + }, + { + "ordinal": 6, + "name": "is_flow", + "type_info": "Bool" + }, + { + "ordinal": 7, + "name": "edited_by", + "type_info": "Varchar" + }, + { + "ordinal": 8, + "name": "email", + "type_info": "Varchar" + }, + { + "ordinal": 9, + "name": "edited_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 10, + "name": "server_id", + "type_info": "Varchar" + }, + { + "ordinal": 11, + "name": "last_server_ping", + "type_info": "Timestamptz" + }, + { + "ordinal": 12, + "name": "extra_perms", + "type_info": "Jsonb" + }, + { + "ordinal": 13, + "name": "error", + "type_info": "Text" + }, + { + "ordinal": 14, + "name": "enabled", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + false, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false + ] + }, + "hash": "2ef82fad8a6ccdc66228cfbce5393de351653ab9ac171fa0eea447c905440867" +} diff --git a/backend/.sqlx/query-3f67e7cf8d9f021a075f1c88703287a9f42e252a1246a584249a224afdbbbf8a.json b/backend/.sqlx/query-3f67e7cf8d9f021a075f1c88703287a9f42e252a1246a584249a224afdbbbf8a.json new file mode 100644 index 0000000000..8dec90897c --- /dev/null +++ b/backend/.sqlx/query-3f67e7cf8d9f021a075f1c88703287a9f42e252a1246a584249a224afdbbbf8a.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger \n SET \n enabled = FALSE, \n error = $1, \n server_id = NULL, \n last_server_ping = NULL \n WHERE \n workspace_id = $2 AND \n path = $3\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "3f67e7cf8d9f021a075f1c88703287a9f42e252a1246a584249a224afdbbbf8a" +} diff --git a/backend/.sqlx/query-5bd8ae8d694ac9f6afef762276141d95ba195f5543120e76e68f6e6715b65a71.json b/backend/.sqlx/query-5bd8ae8d694ac9f6afef762276141d95ba195f5543120e76e68f6e6715b65a71.json new file mode 100644 index 0000000000..31700319e2 --- /dev/null +++ b/backend/.sqlx/query-5bd8ae8d694ac9f6afef762276141d95ba195f5543120e76e68f6e6715b65a71.json @@ -0,0 +1,24 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger \n SET \n server_id = $1, \n last_server_ping = now(),\n error = 'Connecting...'\n WHERE \n enabled IS TRUE \n AND workspace_id = $2 \n AND path = $3 \n AND (last_server_ping IS NULL \n OR last_server_ping < now() - INTERVAL '15 seconds'\n ) \n RETURNING true\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Varchar", + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "5bd8ae8d694ac9f6afef762276141d95ba195f5543120e76e68f6e6715b65a71" +} diff --git a/backend/.sqlx/query-5c1de8473e0e96c1063a9a735a064c5a91e3ed8d9260c72b783fc12542b88fbd.json b/backend/.sqlx/query-5c1de8473e0e96c1063a9a735a064c5a91e3ed8d9260c72b783fc12542b88fbd.json index b6461d711f..0184cadf74 100644 --- a/backend/.sqlx/query-5c1de8473e0e96c1063a9a735a064c5a91e3ed8d9260c72b783fc12542b88fbd.json +++ b/backend/.sqlx/query-5c1de8473e0e96c1063a9a735a064c5a91e3ed8d9260c72b783fc12542b88fbd.json @@ -27,7 +27,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } @@ -60,7 +61,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-62475252dcf54f32433b97ae011daf5d4205d160d2aedf463c7dfe944e93257a.json b/backend/.sqlx/query-62475252dcf54f32433b97ae011daf5d4205d160d2aedf463c7dfe944e93257a.json index d99d288b08..9e86b3dbf4 100644 --- a/backend/.sqlx/query-62475252dcf54f32433b97ae011daf5d4205d160d2aedf463c7dfe944e93257a.json +++ b/backend/.sqlx/query-62475252dcf54f32433b97ae011daf5d4205d160d2aedf463c7dfe944e93257a.json @@ -19,7 +19,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-6b776693091191f36eaf9e35fb3cabb01481a19bef5a956dc36cac41acad0e53.json b/backend/.sqlx/query-6b776693091191f36eaf9e35fb3cabb01481a19bef5a956dc36cac41acad0e53.json new file mode 100644 index 0000000000..97079df64f --- /dev/null +++ b/backend/.sqlx/query-6b776693091191f36eaf9e35fb3cabb01481a19bef5a956dc36cac41acad0e53.json @@ -0,0 +1,25 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n capture_config \n SET \n server_id = $1,\n last_server_ping = now(), \n error = 'Connecting...' \n WHERE \n last_client_ping > NOW() - INTERVAL '10 seconds' AND \n workspace_id = $2 AND \n path = $3 AND \n is_flow = $4 AND \n trigger_kind = 'sqs' AND \n (last_server_ping IS NULL OR last_server_ping < now() - interval '15 seconds') \n RETURNING true\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Varchar", + "Text", + "Text", + "Bool" + ] + }, + "nullable": [ + null + ] + }, + "hash": "6b776693091191f36eaf9e35fb3cabb01481a19bef5a956dc36cac41acad0e53" +} diff --git a/backend/.sqlx/query-71d51bbc35da7b9930e3ea3a634451217ccb9f1bc35b1ad6e10d16bc19c41447.json b/backend/.sqlx/query-71d51bbc35da7b9930e3ea3a634451217ccb9f1bc35b1ad6e10d16bc19c41447.json index 1a61219096..4b5e3a41fd 100644 --- a/backend/.sqlx/query-71d51bbc35da7b9930e3ea3a634451217ccb9f1bc35b1ad6e10d16bc19c41447.json +++ b/backend/.sqlx/query-71d51bbc35da7b9930e3ea3a634451217ccb9f1bc35b1ad6e10d16bc19c41447.json @@ -30,7 +30,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-7e31c47e02492b74cbb5702dfc5ef9f4c8faa986843024a2cd58e212f706aae8.json b/backend/.sqlx/query-7e31c47e02492b74cbb5702dfc5ef9f4c8faa986843024a2cd58e212f706aae8.json new file mode 100644 index 0000000000..eea1cfa434 --- /dev/null +++ b/backend/.sqlx/query-7e31c47e02492b74cbb5702dfc5ef9f4c8faa986843024a2cd58e212f706aae8.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n capture_config \n SET \n error = $1, \n server_id = NULL, \n last_server_ping = NULL \n WHERE \n workspace_id = $2 AND \n path = $3 AND \n is_flow = $4 AND \n trigger_kind = 'sqs'\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Bool" + ] + }, + "nullable": [] + }, + "hash": "7e31c47e02492b74cbb5702dfc5ef9f4c8faa986843024a2cd58e212f706aae8" +} diff --git a/backend/.sqlx/query-93d0ee34c7b7c56ab9cae28071f8e5fdaff0e601e2760cc5653d197c51b106bb.json b/backend/.sqlx/query-93d0ee34c7b7c56ab9cae28071f8e5fdaff0e601e2760cc5653d197c51b106bb.json new file mode 100644 index 0000000000..1945784892 --- /dev/null +++ b/backend/.sqlx/query-93d0ee34c7b7c56ab9cae28071f8e5fdaff0e601e2760cc5653d197c51b106bb.json @@ -0,0 +1,52 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT \n \n EXISTS(SELECT 1 FROM websocket_trigger WHERE workspace_id = $1) AS \"websocket_used!\", \n \n EXISTS(SELECT 1 FROM http_trigger WHERE workspace_id = $1) AS \"http_routes_used!\",\n EXISTS(SELECT 1 FROM kafka_trigger WHERE workspace_id = $1) as \"kafka_used!\",\n EXISTS(SELECT 1 FROM nats_trigger WHERE workspace_id = $1) as \"nats_used!\",\n EXISTS(SELECT 1 FROM postgres_trigger WHERE workspace_id = $1) AS \"postgres_used!\",\n EXISTS(SELECT 1 FROM sqs_trigger WHERE workspace_id = $1) AS \"sqs_used!\"\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "websocket_used!", + "type_info": "Bool" + }, + { + "ordinal": 1, + "name": "http_routes_used!", + "type_info": "Bool" + }, + { + "ordinal": 2, + "name": "kafka_used!", + "type_info": "Bool" + }, + { + "ordinal": 3, + "name": "nats_used!", + "type_info": "Bool" + }, + { + "ordinal": 4, + "name": "postgres_used!", + "type_info": "Bool" + }, + { + "ordinal": 5, + "name": "sqs_used!", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null, + null, + null, + null, + null, + null + ] + }, + "hash": "93d0ee34c7b7c56ab9cae28071f8e5fdaff0e601e2760cc5653d197c51b106bb" +} diff --git a/backend/.sqlx/query-9b9bc21023f10a0b4bb45879c7da8e119bffd2982b97fc900358506a0a14bbb8.json b/backend/.sqlx/query-9b9bc21023f10a0b4bb45879c7da8e119bffd2982b97fc900358506a0a14bbb8.json new file mode 100644 index 0000000000..de9b6ea295 --- /dev/null +++ b/backend/.sqlx/query-9b9bc21023f10a0b4bb45879c7da8e119bffd2982b97fc900358506a0a14bbb8.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO sqs_trigger (\n aws_resource_path,\n queue_url,\n message_attributes,\n workspace_id, \n path, \n script_path, \n is_flow, \n email, \n enabled, \n edited_by\n ) \n VALUES (\n $1, \n $2, \n $3, \n $4, \n $5, \n $6, \n $7,\n $8,\n $9,\n $10\n )", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "TextArray", + "Varchar", + "Varchar", + "Varchar", + "Bool", + "Varchar", + "Bool", + "Varchar" + ] + }, + "nullable": [] + }, + "hash": "9b9bc21023f10a0b4bb45879c7da8e119bffd2982b97fc900358506a0a14bbb8" +} diff --git a/backend/.sqlx/query-a5fbef9db2308920ea26f6154f0f3490f88ced636c9ebdecba2205f964b1d0f1.json b/backend/.sqlx/query-a5fbef9db2308920ea26f6154f0f3490f88ced636c9ebdecba2205f964b1d0f1.json new file mode 100644 index 0000000000..219558ac68 --- /dev/null +++ b/backend/.sqlx/query-a5fbef9db2308920ea26f6154f0f3490f88ced636c9ebdecba2205f964b1d0f1.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger \n SET\n last_server_ping = NULL \n WHERE \n workspace_id = $1 \n AND path = $2 \n AND server_id IS NULL", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "a5fbef9db2308920ea26f6154f0f3490f88ced636c9ebdecba2205f964b1d0f1" +} diff --git a/backend/.sqlx/query-b386d320f9fe1d569a16e6626b723b4376a93342702856da2ac70f6bbfc7933e.json b/backend/.sqlx/query-b386d320f9fe1d569a16e6626b723b4376a93342702856da2ac70f6bbfc7933e.json new file mode 100644 index 0000000000..13ac3c15ea --- /dev/null +++ b/backend/.sqlx/query-b386d320f9fe1d569a16e6626b723b4376a93342702856da2ac70f6bbfc7933e.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT EXISTS(\n SELECT \n 1 \n FROM \n sqs_trigger \n WHERE \n path = $1 AND \n workspace_id = $2\n )", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "b386d320f9fe1d569a16e6626b723b4376a93342702856da2ac70f6bbfc7933e" +} diff --git a/backend/.sqlx/query-c223f8b7fa4ef1aa06e1ba2a56d677774aa237508d5610714efd2e9b8b93c7b8.json b/backend/.sqlx/query-c223f8b7fa4ef1aa06e1ba2a56d677774aa237508d5610714efd2e9b8b93c7b8.json index b5c5aa2cb7..a2d04fed03 100644 --- a/backend/.sqlx/query-c223f8b7fa4ef1aa06e1ba2a56d677774aa237508d5610714efd2e9b8b93c7b8.json +++ b/backend/.sqlx/query-c223f8b7fa4ef1aa06e1ba2a56d677774aa237508d5610714efd2e9b8b93c7b8.json @@ -22,7 +22,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-c5270ee815689e42b65df507b850da43239c9a5aaea41c9aed7ed33a6219a534.json b/backend/.sqlx/query-c5270ee815689e42b65df507b850da43239c9a5aaea41c9aed7ed33a6219a534.json index 6f08506fdf..e29d94f8f5 100644 --- a/backend/.sqlx/query-c5270ee815689e42b65df507b850da43239c9a5aaea41c9aed7ed33a6219a534.json +++ b/backend/.sqlx/query-c5270ee815689e42b65df507b850da43239c9a5aaea41c9aed7ed33a6219a534.json @@ -19,7 +19,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-ddf2eccb78a310ed00c7d8b9c3f05d394a7cbcf0038c72a78add5c7b02ef5927.json b/backend/.sqlx/query-ddf2eccb78a310ed00c7d8b9c3f05d394a7cbcf0038c72a78add5c7b02ef5927.json index c2dfed73a2..5bfff47576 100644 --- a/backend/.sqlx/query-ddf2eccb78a310ed00c7d8b9c3f05d394a7cbcf0038c72a78add5c7b02ef5927.json +++ b/backend/.sqlx/query-ddf2eccb78a310ed00c7d8b9c3f05d394a7cbcf0038c72a78add5c7b02ef5927.json @@ -15,7 +15,7 @@ ] }, "nullable": [ - null + true ] }, "hash": "ddf2eccb78a310ed00c7d8b9c3f05d394a7cbcf0038c72a78add5c7b02ef5927" diff --git a/backend/.sqlx/query-dea056c89313f4facd62cbbc9fa33ba30fa85efcc83fafe4dd7b4e535b96a8d8.json b/backend/.sqlx/query-dea056c89313f4facd62cbbc9fa33ba30fa85efcc83fafe4dd7b4e535b96a8d8.json new file mode 100644 index 0000000000..12e4b6d81b --- /dev/null +++ b/backend/.sqlx/query-dea056c89313f4facd62cbbc9fa33ba30fa85efcc83fafe4dd7b4e535b96a8d8.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n DELETE \n FROM \n sqs_trigger \n WHERE \n workspace_id = $1 AND \n path = $2\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "dea056c89313f4facd62cbbc9fa33ba30fa85efcc83fafe4dd7b4e535b96a8d8" +} diff --git a/backend/.sqlx/query-e17ec84003e2ec414622d100f5dfdda86bee33f31835317df512a20c805b35d7.json b/backend/.sqlx/query-e17ec84003e2ec414622d100f5dfdda86bee33f31835317df512a20c805b35d7.json index 7e7155a6b4..66578654a3 100644 --- a/backend/.sqlx/query-e17ec84003e2ec414622d100f5dfdda86bee33f31835317df512a20c805b35d7.json +++ b/backend/.sqlx/query-e17ec84003e2ec414622d100f5dfdda86bee33f31835317df512a20c805b35d7.json @@ -27,7 +27,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-e23e110e1f0438d21534fc4323e0e7bc1f0dbeca2e4f44ced05bae0ca5ca1039.json b/backend/.sqlx/query-e23e110e1f0438d21534fc4323e0e7bc1f0dbeca2e4f44ced05bae0ca5ca1039.json index 488355d34e..8d3bf8c927 100644 --- a/backend/.sqlx/query-e23e110e1f0438d21534fc4323e0e7bc1f0dbeca2e4f44ced05bae0ca5ca1039.json +++ b/backend/.sqlx/query-e23e110e1f0438d21534fc4323e0e7bc1f0dbeca2e4f44ced05bae0ca5ca1039.json @@ -35,7 +35,8 @@ "kafka", "email", "nats", - "postgres" + "postgres", + "sqs" ] } } diff --git a/backend/.sqlx/query-e6adaebcade2e25be800e8b888b23c94caae2421f3cae7c06d6346bd6de1d94a.json b/backend/.sqlx/query-e6adaebcade2e25be800e8b888b23c94caae2421f3cae7c06d6346bd6de1d94a.json new file mode 100644 index 0000000000..9715083ee6 --- /dev/null +++ b/backend/.sqlx/query-e6adaebcade2e25be800e8b888b23c94caae2421f3cae7c06d6346bd6de1d94a.json @@ -0,0 +1,104 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n queue_url,\n aws_resource_path,\n message_attributes,\n workspace_id,\n path,\n script_path,\n is_flow,\n edited_by,\n email,\n edited_at,\n server_id,\n last_server_ping,\n extra_perms,\n error,\n enabled\n FROM\n sqs_trigger\n WHERE\n enabled IS TRUE\n AND (last_server_ping IS NULL OR\n last_server_ping < now() - interval '15 seconds'\n )\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "queue_url", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "aws_resource_path", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "message_attributes", + "type_info": "TextArray" + }, + { + "ordinal": 3, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 5, + "name": "script_path", + "type_info": "Varchar" + }, + { + "ordinal": 6, + "name": "is_flow", + "type_info": "Bool" + }, + { + "ordinal": 7, + "name": "edited_by", + "type_info": "Varchar" + }, + { + "ordinal": 8, + "name": "email", + "type_info": "Varchar" + }, + { + "ordinal": 9, + "name": "edited_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 10, + "name": "server_id", + "type_info": "Varchar" + }, + { + "ordinal": 11, + "name": "last_server_ping", + "type_info": "Timestamptz" + }, + { + "ordinal": 12, + "name": "extra_perms", + "type_info": "Jsonb" + }, + { + "ordinal": 13, + "name": "error", + "type_info": "Text" + }, + { + "ordinal": 14, + "name": "enabled", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + true, + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + true, + false + ] + }, + "hash": "e6adaebcade2e25be800e8b888b23c94caae2421f3cae7c06d6346bd6de1d94a" +} diff --git a/backend/.sqlx/query-f68d23841e0e31cdf8633aaf0f32777e04e4965682e5b37afbe84194b756d5f5.json b/backend/.sqlx/query-f68d23841e0e31cdf8633aaf0f32777e04e4965682e5b37afbe84194b756d5f5.json new file mode 100644 index 0000000000..aa29c1b4dd --- /dev/null +++ b/backend/.sqlx/query-f68d23841e0e31cdf8633aaf0f32777e04e4965682e5b37afbe84194b756d5f5.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE \n sqs_trigger \n SET \n aws_resource_path = $1,\n queue_url = $2,\n message_attributes = $3, \n is_flow = $4, \n edited_by = $5, \n email = $6,\n script_path = $7,\n path = $8,\n edited_at = now(), \n error = NULL,\n server_id = NULL\n WHERE \n workspace_id = $9 AND \n path = $10\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "TextArray", + "Bool", + "Varchar", + "Varchar", + "Varchar", + "Varchar", + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "f68d23841e0e31cdf8633aaf0f32777e04e4965682e5b37afbe84194b756d5f5" +} diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json index ab8340f5c8..6ebd36cf07 100644 --- a/backend/.vscode/settings.json +++ b/backend/.vscode/settings.json @@ -11,5 +11,5 @@ "remote.autoForwardPorts": true, "conventionalCommits.scopes": [ "restructring triggers, decoding trigger message on work" - ], + ] } diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 73f3686217..282b6f9aba 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -716,6 +716,28 @@ dependencies = [ "uuid 1.13.2", ] +[[package]] +name = "aws-sdk-sqs" +version = "1.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03247b11956444de4699fb0b84ed32989ed9530900020d7fb8983174b5b358f9" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "http 0.2.12", + "once_cell", + "regex-lite", + "tracing", +] + [[package]] name = "aws-sdk-sso" version = "1.59.0" @@ -10912,6 +10934,8 @@ dependencies = [ "async-stream", "async-stripe", "async_zip", + "aws-config", + "aws-sdk-sqs", "axum", "base32", "base64 0.22.1", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index e3088ef581..cbaffe175c 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -74,6 +74,7 @@ mssql = ["windmill-worker/mssql"] bigquery = ["windmill-worker/bigquery"] websocket = ["windmill-api/websocket"] postgres_trigger = ["windmill-api/postgres_trigger"] +sqs_trigger = ["windmill-api/sqs_trigger"] python = ["windmill-worker/python"] smtp = ["windmill-api/smtp", "windmill-common/smtp"] csharp = ["windmill-worker/csharp"] @@ -306,6 +307,7 @@ datafusion = "39.0.0" object_store = { version = "0.10.0", features = ["aws", "azure"] } openidconnect = { version = "4.0.0-rc.1" } aws-config = "^1" +aws-sdk-sqs = "1.57.0" aws-sdk-sts = "^1" crc = "^3" diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 562c984114..efebd317f9 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -5d25cf2cd15c1953794045fd7debea14a33c7519 \ No newline at end of file +5e7e98536a8eb632961b3b597deac95aaca1cdbe \ No newline at end of file diff --git a/backend/migrations/20250130184358_sqs_trigger.down.sql b/backend/migrations/20250130184358_sqs_trigger.down.sql new file mode 100644 index 0000000000..5b91b856ad --- /dev/null +++ b/backend/migrations/20250130184358_sqs_trigger.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS sqs_trigger; \ No newline at end of file diff --git a/backend/migrations/20250130184358_sqs_trigger.up.sql b/backend/migrations/20250130184358_sqs_trigger.up.sql new file mode 100644 index 0000000000..aaa219b1de --- /dev/null +++ b/backend/migrations/20250130184358_sqs_trigger.up.sql @@ -0,0 +1,69 @@ +-- Add up migration script here +CREATE TABLE sqs_trigger( + path VARCHAR(255) NOT NULL, + queue_url VARCHAR(255) NOT NULL, + aws_resource_path VARCHAR(255) NOT NULL, + message_attributes TEXT[], + script_path VARCHAR(255) NOT NULL, + is_flow BOOLEAN NOT NULL, + workspace_id VARCHAR(50) NOT NULL, + edited_by VARCHAR(50) NOT NULL, + email VARCHAR(255) NOT NULL, + edited_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + extra_perms JSONB NULL, + error TEXT NULL, + server_id VARCHAR(50) NULL, + last_server_ping TIMESTAMPTZ NULL, + enabled BOOLEAN NOT NULL, + CONSTRAINT PK_sqs_trigger PRIMARY KEY (path,workspace_id), + CONSTRAINT fk_sqs_trigger_workspace FOREIGN KEY (workspace_id) + REFERENCES workspace(id) ON DELETE CASCADE +); + +GRANT ALL ON sqs_trigger TO windmill_user; +GRANT ALL ON sqs_trigger TO windmill_admin; + +ALTER TABLE sqs_trigger ENABLE ROW LEVEL SECURITY; + +CREATE POLICY admin_policy ON sqs_trigger FOR ALL TO windmill_admin USING (true); + +CREATE POLICY see_folder_extra_perms_user_select ON sqs_trigger FOR SELECT TO windmill_user +USING (SPLIT_PART(sqs_trigger.path, '/', 1) = 'f' AND SPLIT_PART(sqs_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_read'), ',')::text[])); +CREATE POLICY see_folder_extra_perms_user_insert ON sqs_trigger FOR INSERT TO windmill_user +WITH CHECK (SPLIT_PART(sqs_trigger.path, '/', 1) = 'f' AND SPLIT_PART(sqs_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_write'), ',')::text[])); +CREATE POLICY see_folder_extra_perms_user_update ON sqs_trigger FOR UPDATE TO windmill_user +USING (SPLIT_PART(sqs_trigger.path, '/', 1) = 'f' AND SPLIT_PART(sqs_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_write'), ',')::text[])); +CREATE POLICY see_folder_extra_perms_user_delete ON sqs_trigger FOR DELETE TO windmill_user +USING (SPLIT_PART(sqs_trigger.path, '/', 1) = 'f' AND SPLIT_PART(sqs_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_write'), ',')::text[])); + +CREATE POLICY see_own ON sqs_trigger FOR ALL TO windmill_user +USING (SPLIT_PART(sqs_trigger.path, '/', 1) = 'u' AND SPLIT_PART(sqs_trigger.path, '/', 2) = current_setting('session.user')); +CREATE POLICY see_member ON sqs_trigger FOR ALL TO windmill_user +USING (SPLIT_PART(sqs_trigger.path, '/', 1) = 'g' AND SPLIT_PART(sqs_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.groups'), ',')::text[])); + +CREATE POLICY see_extra_perms_user_select ON sqs_trigger FOR SELECT TO windmill_user +USING (extra_perms ? CONCAT('u/', current_setting('session.user'))); +CREATE POLICY see_extra_perms_user_insert ON sqs_trigger FOR INSERT TO windmill_user +WITH CHECK ((extra_perms ->> CONCAT('u/', current_setting('session.user')))::boolean); +CREATE POLICY see_extra_perms_user_update ON sqs_trigger FOR UPDATE TO windmill_user +USING ((extra_perms ->> CONCAT('u/', current_setting('session.user')))::boolean); +CREATE POLICY see_extra_perms_user_delete ON sqs_trigger FOR DELETE TO windmill_user +USING ((extra_perms ->> CONCAT('u/', current_setting('session.user')))::boolean); + +CREATE POLICY see_extra_perms_groups_select ON sqs_trigger FOR SELECT TO windmill_user +USING (extra_perms ?| regexp_split_to_array(current_setting('session.pgroups'), ',')::text[]); +CREATE POLICY see_extra_perms_groups_insert ON sqs_trigger FOR INSERT TO windmill_user +WITH CHECK (exists( + SELECT key, value FROM jsonb_each_text(extra_perms) + WHERE SPLIT_PART(key, '/', 1) = 'g' AND key = ANY(regexp_split_to_array(current_setting('session.pgroups'), ',')::text[]) + AND value::boolean)); +CREATE POLICY see_extra_perms_groups_update ON sqs_trigger FOR UPDATE TO windmill_user +USING (exists( + SELECT key, value FROM jsonb_each_text(extra_perms) + WHERE SPLIT_PART(key, '/', 1) = 'g' AND key = ANY(regexp_split_to_array(current_setting('session.pgroups'), ',')::text[]) + AND value::boolean)); +CREATE POLICY see_extra_perms_groups_delete ON sqs_trigger FOR DELETE TO windmill_user +USING (exists( + SELECT key, value FROM jsonb_each_text(extra_perms) + WHERE SPLIT_PART(key, '/', 1) = 'g' AND key = ANY(regexp_split_to_array(current_setting('session.pgroups'), ',')::text[]) + AND value::boolean)); \ No newline at end of file diff --git a/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.down.sql b/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.down.sql new file mode 100644 index 0000000000..0197d4e7b1 --- /dev/null +++ b/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.down.sql @@ -0,0 +1 @@ +-- Add down migration script here \ No newline at end of file diff --git a/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.up.sql b/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.up.sql new file mode 100644 index 0000000000..2281aeba2a --- /dev/null +++ b/backend/migrations/20250205003539_add_sqs_type_value_to_trigger_kind_type.up.sql @@ -0,0 +1,2 @@ +-- Add up migration script here +ALTER TYPE TRIGGER_KIND ADD VALUE IF NOT EXISTS 'sqs'; \ No newline at end of file diff --git a/backend/src/main.rs b/backend/src/main.rs index 0dfda31bcf..ab74895ca8 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -899,6 +899,7 @@ Windmill Community Edition {GIT_VERSION} let metrics_f = async { let enabled = METRICS_ENABLED.load(std::sync::atomic::Ordering::Relaxed); + #[cfg(not(all(feature = "enterprise", feature = "prometheus")))] if enabled { tracing::error!("Metrics are only available in the EE, ignoring..."); diff --git a/backend/windmill-api/Cargo.toml b/backend/windmill-api/Cargo.toml index 675aeec0b1..d5f8f6f420 100644 --- a/backend/windmill-api/Cargo.toml +++ b/backend/windmill-api/Cargo.toml @@ -29,6 +29,7 @@ oauth2 = ["dep:async-oauth2"] http_trigger = ["dep:matchit"] static_frontend = ["dep:rust-embed"] postgres_trigger = ["dep:rust-postgres", "dep:pg_escape", "dep:byteorder", "dep:thiserror", "dep:rust_decimal", "dep:rust-postgres-native-tls"] +sqs_trigger = ["dep:aws-sdk-sqs", "dep:thiserror", "dep:aws-config"] [dependencies] windmill-queue.workspace = true @@ -118,4 +119,6 @@ pg_escape = { workspace = true, optional = true } byteorder = { workspace = true, optional = true } thiserror = { workspace = true, optional = true } rust_decimal = { workspace = true, optional = true } -rust-postgres-native-tls = { workspace = true, optional = true} \ No newline at end of file +rust-postgres-native-tls = { workspace = true, optional = true} +aws-sdk-sqs = { workspace = true, optional = true } +aws-config = { workspace = true, optional = true} \ No newline at end of file diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index dca954119e..41abe815a7 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -2611,12 +2611,15 @@ paths: type: boolean postgres_used: type: boolean + sqs_used: + type: boolean required: - http_routes_used - websocket_used - kafka_used - nats_used - postgres_used + - sqs_used /w/{workspace}/users/list: get: summary: list users @@ -8564,6 +8567,196 @@ paths: schema: type: string + /w/{workspace}/sqs_triggers/create: + post: + summary: create sqs trigger + operationId: createSqsTrigger + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: new sqs trigger + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/NewSqsTrigger" + responses: + "201": + description: sqs trigger created + content: + text/plain: + schema: + type: string + + /w/{workspace}/sqs_triggers/update/{path}: + post: + summary: update sqs trigger + operationId: updateSqsTrigger + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + requestBody: + description: updated trigger + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/EditSqsTrigger" + responses: + "200": + description: sqs trigger updated + content: + text/plain: + schema: + type: string + + /w/{workspace}/sqs_triggers/delete/{path}: + delete: + summary: delete sqs trigger + operationId: deleteSqsTrigger + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + responses: + "200": + description: sqs trigger deleted + content: + text/plain: + schema: + type: string + + /w/{workspace}/sqs_triggers/get/{path}: + get: + summary: get sqs trigger + operationId: getSqsTrigger + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + responses: + "200": + description: sqs trigger deleted + content: + application/json: + schema: + $ref: "#/components/schemas/SqsTrigger" + + /w/{workspace}/sqs_triggers/list: + get: + summary: list sqs triggers + operationId: listSqsTriggers + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + required: true + - $ref: "#/components/parameters/Page" + - $ref: "#/components/parameters/PerPage" + - name: path + description: filter by path + in: query + schema: + type: string + - name: is_flow + in: query + schema: + type: boolean + - name: path_start + in: query + schema: + type: string + responses: + "200": + description: sqs trigger list + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/SqsTrigger" + + /w/{workspace}/sqs_triggers/exists/{path}: + get: + summary: does sqs trigger exists + operationId: existsSqsTrigger + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + responses: + "200": + description: sqs trigger exists + content: + application/json: + schema: + type: boolean + + /w/{workspace}/sqs_triggers/setenabled/{path}: + post: + summary: set enabled sqs trigger + operationId: setSqsTriggerEnabled + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + requestBody: + description: updated sqs trigger enable + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + required: + - enabled + responses: + "200": + description: sqs trigger enabled set + content: + text/plain: + schema: + type: string + + /w/{workspace}/sqs_triggers/test: + post: + summary: test sqs connection + operationId: testSqsConnection + tags: + - sqs_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + requestBody: + description: test sqs connection + required: true + content: + application/json: + schema: + type: object + properties: + connection: + type: object + required: + - connection + responses: + "200": + description: successfuly connected to sqs + content: + text/plain: + schema: + type: string + + /w/{workspace}/postgres_triggers/is_valid_postgres_configuration/{path}: get: summary: check if postgres configuration is set to logical @@ -9851,6 +10044,7 @@ paths: kafka_trigger, nats_trigger, postgres_trigger, + sqs_trigger ] responses: "200": @@ -9892,6 +10086,7 @@ paths: kafka_trigger, nats_trigger, postgres_trigger, + sqs_trigger ] requestBody: description: acl to add @@ -9944,6 +10139,7 @@ paths: kafka_trigger, nats_trigger, postgres_trigger, + sqs_trigger ] requestBody: description: acl to add @@ -13166,6 +13362,10 @@ components: TriggerExtraProperty: type: object properties: + path: + type: string + script_path: + type: string email: type: string extra_perms: @@ -13179,22 +13379,23 @@ components: edited_at: type: string format: date-time + is_flow: + type: boolean required: + - path + - script_path - email - extra_perms - workspace_id - edited_by - edited_at + - is_flow HttpTrigger: allOf: - $ref: "#/components/schemas/TriggerExtraProperty" type: object properties: - path: - type: string - script_path: - type: string route_path: type: string static_asset_config: @@ -13208,8 +13409,6 @@ components: type: string required: - s3 - is_flow: - type: boolean http_method: type: string enum: @@ -13226,15 +13425,7 @@ components: type: boolean required: - - path - - edited_by - - edited_at - - script_path - route_path - - extra_perms - - is_flow - - email - - workspace_id - is_async - requires_auth - http_method @@ -13357,20 +13548,16 @@ components: type: number nats_count: type: number + sqs_count: + type: number WebsocketTrigger: allOf: - $ref: "#/components/schemas/TriggerExtraProperty" type: object properties: - path: - type: string - script_path: - type: string url: type: string - is_flow: - type: boolean server_id: type: string last_server_ping: @@ -13401,15 +13588,7 @@ components: type: boolean required: - - path - - edited_by - - edited_at - - script_path - url - - extra_perms - - is_flow - - email - - workspace_id - enabled - filters - can_return_message @@ -13519,6 +13698,88 @@ components: required: - runnable_result + SqsTrigger: + allOf: + - $ref: "#/components/schemas/TriggerExtraProperty" + type: object + properties: + queue_url: + type: string + aws_resource_path: + type: string + message_attributes: + type: array + items: + type: string + server_id: + type: string + last_server_ping: + type: string + format: date-time + error: + type: string + enabled: + type: boolean + + required: + - queue_url + - aws_resource_path + - enabled + + NewSqsTrigger: + type: object + properties: + queue_url: + type: string + aws_resource_path: + type: string + message_attributes: + type: array + items: + type: string + path: + type: string + script_path: + type: string + is_flow: + type: boolean + enabled: + type: boolean + required: + - queue_url + - aws_resource_path + - path + - script_path + - is_flow + + EditSqsTrigger: + type: object + properties: + queue_url: + type: string + aws_resource_path: + type: string + message_attributes: + type: array + items: + type: string + path: + type: string + script_path: + type: string + is_flow: + type: boolean + enabled: + type: boolean + required: + - queue_url + - aws_resource_path + - path + - script_path + - is_flow + - enabled + + Slot: type: object properties: @@ -13600,12 +13861,6 @@ components: - $ref: "#/components/schemas/TriggerExtraProperty" type: object properties: - path: - type: string - script_path: - type: string - is_flow: - type: boolean enabled: type: boolean postgres_resource_path: @@ -13622,9 +13877,6 @@ components: type: string format: date-time required: - - path - - script_path - - is_flow - enabled - postgres_resource_path - replication_slot_name @@ -13685,17 +13937,10 @@ components: - replication_slot_name KafkaTrigger: + allOf: + - $ref: "#/components/schemas/TriggerExtraProperty" type: object properties: - path: - type: string - edited_by: - type: string - edited_at: - type: string - format: date-time - script_path: - type: string kafka_resource_path: type: string group_id: @@ -13704,16 +13949,6 @@ components: type: array items: type: string - is_flow: - type: boolean - extra_perms: - type: object - additionalProperties: - type: boolean - email: - type: string - workspace_id: - type: string server_id: type: string last_server_ping: @@ -13725,17 +13960,9 @@ components: type: boolean required: - - path - - edited_by - - edited_at - - script_path - kafka_resource_path - group_id - topics - - extra_perms - - is_flow - - email - - workspace_id - enabled NewKafkaTrigger: @@ -13793,17 +14020,10 @@ components: - is_flow NatsTrigger: + allOf: + - $ref: "#/components/schemas/TriggerExtraProperty" type: object properties: - path: - type: string - edited_by: - type: string - edited_at: - type: string - format: date-time - script_path: - type: string nats_resource_path: type: string use_jetstream: @@ -13816,16 +14036,6 @@ components: type: array items: type: string - is_flow: - type: boolean - extra_perms: - type: object - additionalProperties: - type: boolean - email: - type: string - workspace_id: - type: string server_id: type: string last_server_ping: @@ -13837,17 +14047,9 @@ components: type: boolean required: - - path - - edited_by - - edited_at - - script_path - nats_resource_path - use_jetstream - subjects - - extra_perms - - is_flow - - email - - workspace_id - enabled NewNatsTrigger: @@ -14867,7 +15069,7 @@ components: CaptureTriggerKind: type: string - enum: [webhook, http, websocket, kafka, email, nats, postgres] + enum: [webhook, http, websocket, kafka, email, nats, postgres, sqs] Capture: type: object diff --git a/backend/windmill-api/src/capture.rs b/backend/windmill-api/src/capture.rs index 664f874c0c..7606822d65 100644 --- a/backend/windmill-api/src/capture.rs +++ b/backend/windmill-api/src/capture.rs @@ -98,6 +98,7 @@ pub enum TriggerKind { Kafka, Email, Nats, + Sqs, Postgres, } @@ -110,6 +111,7 @@ impl fmt::Display for TriggerKind { TriggerKind::Kafka => "kafka", TriggerKind::Email => "email", TriggerKind::Nats => "nats", + TriggerKind::Sqs => "sqs", TriggerKind::Postgres => "postgres", }; write!(f, "{}", s) @@ -132,6 +134,14 @@ pub struct KafkaTriggerConfig { pub group_id: String, } +#[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] +#[derive(Debug, Serialize, Deserialize)] +pub struct SqsTriggerConfig { + pub queue_url: String, + pub aws_resource_path: String, + pub message_attributes: Option> +} + #[cfg(all(feature = "enterprise", feature = "nats"))] #[derive(Serialize, Deserialize)] pub struct NatsTriggerConfig { @@ -171,6 +181,8 @@ enum TriggerConfig { Postgres(PostgresTriggerConfig), #[cfg(feature = "websocket")] Websocket(WebsocketTriggerConfig), + #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] + Sqs(SqsTriggerConfig), #[cfg(all(feature = "enterprise", feature = "kafka"))] Kafka(KafkaTriggerConfig), #[cfg(all(feature = "enterprise", feature = "nats"))] diff --git a/backend/windmill-api/src/kafka_triggers_ee.rs b/backend/windmill-api/src/kafka_triggers_ee.rs index de50eea53b..0a24151ae3 100644 --- a/backend/windmill-api/src/kafka_triggers_ee.rs +++ b/backend/windmill-api/src/kafka_triggers_ee.rs @@ -39,4 +39,4 @@ pub struct KafkaTrigger { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, pub enabled: bool, -} +} \ No newline at end of file diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index 4199494ed4..57a49dc724 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -105,6 +105,8 @@ mod settings; mod slack_approvals; #[cfg(feature = "smtp")] mod smtp_server_ee; +#[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] +mod sqs_triggers_ee; mod static_assets; mod stripe_ee; mod teams_ee; @@ -319,6 +321,48 @@ pub async fn run_server( } }; + let sqs_triggers_service = { + #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] + { + sqs_triggers_ee::workspaced_service() + } + + #[cfg(not(all(feature = "enterprise", feature = "sqs_trigger")))] + { + Router::new() + } + }; + + let websocket_triggers_service = { + #[cfg(feature = "websocket")] + { + websocket_triggers::workspaced_service() + } + + #[cfg(not(feature = "websocket"))] + Router::new() + }; + + let http_triggers_service = { + #[cfg(feature = "http_trigger")] + { + http_triggers::workspaced_service() + } + + #[cfg(not(feature = "http_trigger"))] + Router::new() + }; + + let postgres_triggers_service = { + #[cfg(feature = "postgres_trigger")] + { + postgres_triggers::workspaced_service() + } + + #[cfg(not(feature = "postgres_trigger"))] + Router::new() + }; + if !*CLOUD_HOSTED { #[cfg(feature = "websocket")] { @@ -337,11 +381,18 @@ pub async fn run_server( let nats_killpill_rx = rx.resubscribe(); nats_triggers_ee::start_nats_consumers(db.clone(), nats_killpill_rx); } + #[cfg(feature = "postgres_trigger")] { let db_killpill_rx = rx.resubscribe(); postgres_triggers::start_database(db.clone(), db_killpill_rx); } + + #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] + { + let sqs_killpill_rx = rx.resubscribe(); + sqs_triggers_ee::start_sqs(db.clone(), sqs_killpill_rx); + } } // build our application with a route @@ -392,35 +443,12 @@ pub async fn run_server( .nest("/variables", variables::workspaced_service()) .nest("/workspaces", workspaces::workspaced_service()) .nest("/oidc", oidc_ee::workspaced_service()) - .nest("/http_triggers", { - #[cfg(feature = "http_trigger")] - { - http_triggers::workspaced_service() - } - - #[cfg(not(feature = "http_trigger"))] - Router::new() - }) - .nest("/websocket_triggers", { - #[cfg(feature = "websocket")] - { - websocket_triggers::workspaced_service() - } - - #[cfg(not(feature = "websocket"))] - Router::new() - }) + .nest("/http_triggers", http_triggers_service) + .nest("/websocket_triggers", websocket_triggers_service) .nest("/kafka_triggers", kafka_triggers_service) .nest("/nats_triggers", nats_triggers_service) - .nest("/postgres_triggers", { - #[cfg(feature = "postgres_trigger")] - { - postgres_triggers::workspaced_service() - } - - #[cfg(not(feature = "postgres_trigger"))] - Router::new() - }), + .nest("/sqs_triggers", sqs_triggers_service) + .nest("/postgres_triggers", postgres_triggers_service), ) .nest("/workspaces", workspaces::global_service()) .nest( diff --git a/backend/windmill-api/src/nats_triggers_ee.rs b/backend/windmill-api/src/nats_triggers_ee.rs index 92894a2a34..649d3a3837 100644 --- a/backend/windmill-api/src/nats_triggers_ee.rs +++ b/backend/windmill-api/src/nats_triggers_ee.rs @@ -40,4 +40,4 @@ pub struct NatsTrigger { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, pub enabled: bool, -} +} \ No newline at end of file diff --git a/backend/windmill-api/src/postgres_triggers/handler.rs b/backend/windmill-api/src/postgres_triggers/handler.rs index 9c37e0968f..4c791eeb8b 100644 --- a/backend/windmill-api/src/postgres_triggers/handler.rs +++ b/backend/windmill-api/src/postgres_triggers/handler.rs @@ -36,11 +36,11 @@ use super::{ use lazy_static::lazy_static; #[derive(FromRow, Serialize, Deserialize, Debug)] -pub struct Database { +pub struct Postgres { pub user: String, pub password: String, pub host: String, - pub port: u16, + pub port: Option, pub dbname: String, #[serde(default)] pub sslmode: String, @@ -113,7 +113,6 @@ pub struct TestPostgres { pub postgres_resource_path: String, } - pub async fn test_postgres_connection( authed: ApiAuthed, Extension(db): Extension, @@ -706,7 +705,7 @@ pub async fn get_publication_info( let publication_data = get_publication_scope_and_transaction(&mut connection, &publication_name).await; - let (all_table, transaction_to_track) = match publication_data { + let (all_table, transaction_to_track) = match publication_data { Ok(pub_data) => pub_data, Err(Error::SqlErr { error: sqlx::Error::RowNotFound, .. }) => { return Err(Error::NotFound( @@ -1457,4 +1456,4 @@ pub async fn is_database_in_logical_level( }; Ok(Json(is_logical)) -} \ No newline at end of file +} diff --git a/backend/windmill-api/src/postgres_triggers/mod.rs b/backend/windmill-api/src/postgres_triggers/mod.rs index f45a8d5b37..d041f1f508 100644 --- a/backend/windmill-api/src/postgres_triggers/mod.rs +++ b/backend/windmill-api/src/postgres_triggers/mod.rs @@ -1,7 +1,7 @@ use crate::{ db::{ApiAuthed, DB}, jobs::{run_flow_by_path_inner, run_script_by_path_inner, RunJobQuery}, - resources::get_resource_value_interpolated_internal, + resources::try_get_resource_from_db_as, users::fetch_api_authed, }; use chrono::Utc; @@ -20,18 +20,17 @@ use axum::{ routing::{delete, get, post}, Router, }; +pub use handler::PostgresTrigger; use handler::{ alter_publication, create_postgres_trigger, create_publication, create_slot, create_template_script, delete_postgres_trigger, delete_publication, drop_slot_name, exists_postgres_trigger, get_postgres_trigger, get_publication_info, get_template_script, is_database_in_logical_level, list_database_publication, list_postgres_triggers, - list_slot_name, set_enabled, test_postgres_connection, update_postgres_trigger, Database, + list_slot_name, set_enabled, test_postgres_connection, update_postgres_trigger, Postgres, Relations, }; -pub use handler::PostgresTrigger; use windmill_common::{db::UserDB, error::Error, utils::StripPath}; use windmill_queue::PushArgsOwned; - mod bool; mod converter; mod handler; @@ -55,13 +54,15 @@ pub async fn get_database_connection( postgres_resource_path: &str, w_id: &str, ) -> std::result::Result { - let database = get_database_resource(authed, user_db, db, postgres_resource_path, w_id).await?; + let database = + try_get_resource_from_db_as::(authed, user_db, db, postgres_resource_path, w_id) + .await?; Ok(get_raw_postgres_connection(&database).await?) } pub async fn get_raw_postgres_connection( - db: &Database, + db: &Postgres, ) -> std::result::Result { let options = { let sslmode = if !db.sslmode.is_empty() { @@ -69,12 +70,19 @@ pub async fn get_raw_postgres_connection( } else { PgSslMode::Prefer }; - let options = PgConnectOptions::new() - .host(&db.host) - .database(&db.dbname) - .port(db.port) - .ssl_mode(sslmode) - .username(&db.user); + let options = { + let inner_options = PgConnectOptions::new() + .host(&db.host) + .database(&db.dbname) + .ssl_mode(sslmode) + .username(&db.user); + + if let Some(port) = db.port { + inner_options.port(port) + } else { + inner_options + } + }; let options = if !db.root_certificate_pem.is_empty() { options.ssl_root_cert_from_pem(db.root_certificate_pem.as_bytes().to_vec()) @@ -202,39 +210,6 @@ pub fn generate_random_string() -> String { format!("{}_{}", timestamp, random_part) } -pub async fn get_database_resource( - authed: ApiAuthed, - user_db: Option, - db: &DB, - database_resource_path: &str, - w_id: &str, -) -> Result { - let resource = get_resource_value_interpolated_internal( - &authed, - user_db, - &db, - &w_id, - &database_resource_path, - None, - "", - ) - .await - .map_err(|_| Error::NotFound("Database resource do not exist".to_string()))?; - - let resource = match resource { - Some(resource) => serde_json::from_value::(resource)?, - None => { - return { - Err(Error::NotFound( - "Database resource do not exist".to_string(), - )) - } - } - }; - - Ok(resource) -} - fn publication_service() -> Router { Router::new() .route("/get/:publication_name/*path", get(get_publication_info)) diff --git a/backend/windmill-api/src/postgres_triggers/trigger.rs b/backend/windmill-api/src/postgres_triggers/trigger.rs index 45be9f6935..5d84cbdba2 100644 --- a/backend/windmill-api/src/postgres_triggers/trigger.rs +++ b/backend/windmill-api/src/postgres_triggers/trigger.rs @@ -4,7 +4,6 @@ use crate::{ capture::{insert_capture_payload, PostgresTriggerConfig, TriggerKind}, db::{ApiAuthed, DB}, postgres_triggers::{ - get_database_resource, relation::RelationConverter, replication_message::{ LogicalReplicationMessage::{Begin, Commit, Delete, Insert, Relation, Type, Update}, @@ -12,7 +11,7 @@ use crate::{ }, run_job, }, - users::fetch_api_authed, + users::fetch_api_authed, resources::try_get_resource_from_db_as, }; use bytes::{BufMut, Bytes, BytesMut}; use chrono::TimeZone; @@ -33,7 +32,7 @@ use windmill_queue::PushArgsOwned; use super::{ drop_logical_replication_slot_query, drop_publication_query, get_database_connection, - handler::{Database, PostgresTrigger}, + handler::{Postgres, PostgresTrigger}, replication_message::PrimaryKeepAliveBody, ERROR_PUBLICATION_NAME_NOT_EXISTS, ERROR_REPLICATION_SLOT_NOT_EXISTS, }; @@ -80,7 +79,7 @@ enum Error { pub struct PostgresSimpleClient(Client); impl PostgresSimpleClient { - async fn new(database: &Database) -> Result { + async fn new(database: &Postgres) -> Result { let ssl_mode = match database.sslmode.as_ref() { "disable" => SslMode::Disable, "" | "prefer" | "allow" => SslMode::Prefer, @@ -98,11 +97,14 @@ impl PostgresSimpleClient { config .dbname(&database.dbname) .host(&database.host) - .port(database.port) .user(&database.user) .ssl_mode(ssl_mode) .replication_mode(rust_postgres::config::ReplicationMode::Logical); + if let Some(port) = database.port { + config.port(port); + }; + if !database.password.is_empty() { config.password(&database.password); } @@ -451,7 +453,7 @@ impl PostgresConfig { PostgresConfig::Capture(capture) => capture.fetch_authed(db).await?, }; - let database = get_database_resource( + let database = try_get_resource_from_db_as::( authed, Some(UserDB::new(db.clone())), &db, diff --git a/backend/windmill-api/src/resources.rs b/backend/windmill-api/src/resources.rs index f3f2285cd0..f41a2b8e5d 100644 --- a/backend/windmill-api/src/resources.rs +++ b/backend/windmill-api/src/resources.rs @@ -515,7 +515,9 @@ pub async fn transform_json_value<'c>( Value::String(y) if y.starts_with("$res:") => { let path = y.strip_prefix("$res:").unwrap(); if path.split("/").count() < 2 { - return Err(Error::internal_err(format!("Invalid resource path: {path}"))); + return Err(Error::internal_err(format!( + "Invalid resource path: {path}" + ))); } let mut tx: Transaction<'_, Postgres> = authed_transaction_or_default(authed, user_db.clone(), db).await?; @@ -1205,3 +1207,44 @@ async fn update_resource_type( Ok(format!("resource_type {} updated", name)) } + +#[cfg(any( + feature = "postgres_trigger", + all(feature = "sqs_trigger", feature = "enterprise") +))] +pub async fn try_get_resource_from_db_as( + authed: ApiAuthed, + user_db: Option, + db: &DB, + resource_path: &str, + w_id: &str, +) -> Result +where + T: serde::de::DeserializeOwned, +{ + let resource = get_resource_value_interpolated_internal( + &authed, + user_db, + &db, + &w_id, + &resource_path, + None, + "", + ) + .await?; + + let resource = match resource { + Some(resource) => serde_json::from_value::(resource) + .map_err(|e| Error::SerdeJson { error: e, location: "resources.rs".to_string() })?, + None => { + return { + Err(Error::NotFound(format!( + "resource at path :{} do not exist", + &resource_path + ))) + } + } + }; + + Ok(resource) +} diff --git a/backend/windmill-api/src/sqs_triggers_ee.rs b/backend/windmill-api/src/sqs_triggers_ee.rs new file mode 100644 index 0000000000..4f7eb6e254 --- /dev/null +++ b/backend/windmill-api/src/sqs_triggers_ee.rs @@ -0,0 +1,31 @@ +use crate::db::DB; +use axum::Router; +use serde::{Deserialize, Serialize}; + + +pub fn workspaced_service() -> Router { + Router::new() +} + +pub fn start_sqs(_db: DB, mut _killpill_rx: tokio::sync::broadcast::Receiver<()>) -> () { + // implementation is not open source +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct SqsTrigger { + pub queue_url: String, + pub aws_resource_path: String, + pub message_attributes: Option>, + pub path: String, + pub script_path: String, + pub is_flow: bool, + pub workspace_id: String, + pub edited_by: String, + pub email: String, + pub edited_at: chrono::DateTime, + pub extra_perms: Option, + pub error: Option, + pub server_id: Option, + pub last_server_ping: Option>, + pub enabled: bool, +} \ No newline at end of file diff --git a/backend/windmill-api/src/variables.rs b/backend/windmill-api/src/variables.rs index 37960e8583..475fe7db98 100644 --- a/backend/windmill-api/src/variables.rs +++ b/backend/windmill-api/src/variables.rs @@ -31,9 +31,9 @@ use windmill_common::{ }; use lazy_static::lazy_static; -use windmill_common::variables::{decrypt, encrypt}; use serde::Deserialize; use sqlx::{Postgres, Transaction}; +use windmill_common::variables::{decrypt, encrypt}; use windmill_git_sync::{handle_deployment_metadata, DeployedObject}; lazy_static! { diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index f5043052e9..ed42bd5b99 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -1362,6 +1362,7 @@ struct UsedTriggers { pub kafka_used: bool, pub nats_used: bool, pub postgres_used: bool, + pub sqs_used: bool } async fn get_used_triggers( @@ -1380,7 +1381,8 @@ async fn get_used_triggers( EXISTS(SELECT 1 FROM http_trigger WHERE workspace_id = $1) AS "http_routes_used!", EXISTS(SELECT 1 FROM kafka_trigger WHERE workspace_id = $1) as "kafka_used!", EXISTS(SELECT 1 FROM nats_trigger WHERE workspace_id = $1) as "nats_used!", - EXISTS(SELECT 1 FROM postgres_trigger WHERE workspace_id = $1) AS "postgres_used!" + EXISTS(SELECT 1 FROM postgres_trigger WHERE workspace_id = $1) AS "postgres_used!", + EXISTS(SELECT 1 FROM sqs_trigger WHERE workspace_id = $1) AS "sqs_used!" "#, w_id ) diff --git a/backend/windmill-api/src/workspaces_export.rs b/backend/windmill-api/src/workspaces_export.rs index c9f15306b3..8c6293bddb 100644 --- a/backend/windmill-api/src/workspaces_export.rs +++ b/backend/windmill-api/src/workspaces_export.rs @@ -594,6 +594,28 @@ pub(crate) async fn tarball_workspace( } } + #[cfg(all(feature = "enterprise", feature = "sqs_trigger"))] + { + let sqs_triggers = sqlx::query_as!( + crate::sqs_triggers_ee::SqsTrigger, + "SELECT * FROM sqs_trigger + WHERE workspace_id = $1", + &w_id + ) + .fetch_all(&mut *tx) + .await?; + + for trigger in sqs_triggers { + let trigger_str = &to_string_without_metadata(&trigger, false, None).unwrap(); + archive + .write_to_archive( + &trigger_str, + &format!("{}.sqs_trigger.json", trigger.path), + ) + .await?; + } + } + #[cfg(all(feature = "enterprise", feature = "nats"))] { let nats_triggers = sqlx::query_as!( diff --git a/backend/windmill-common/src/variables.rs b/backend/windmill-common/src/variables.rs index 48746152ef..1817945705 100644 --- a/backend/windmill-common/src/variables.rs +++ b/backend/windmill-common/src/variables.rs @@ -352,3 +352,4 @@ pub async fn get_reserved_variables( is_custom: true, })).collect() } + diff --git a/cli/gen/core/OpenAPI.ts b/cli/gen/core/OpenAPI.ts index 4488a855bf..7dbf2fb3d4 100644 --- a/cli/gen/core/OpenAPI.ts +++ b/cli/gen/core/OpenAPI.ts @@ -54,7 +54,7 @@ export const OpenAPI: OpenAPIConfig = { PASSWORD: undefined, TOKEN: getEnv("WM_TOKEN"), USERNAME: undefined, - VERSION: '1.457.1', + VERSION: '1.460.1', WITH_CREDENTIALS: true, interceptors: { request: new Interceptors(), diff --git a/cli/gen/services.gen.ts b/cli/gen/services.gen.ts index 4992329350..5148049bc9 100644 --- a/cli/gen/services.gen.ts +++ b/cli/gen/services.gen.ts @@ -3,7 +3,7 @@ import type { CancelablePromise } from './core/CancelablePromise.ts'; import { OpenAPI } from './core/OpenAPI.ts'; import { request as __request } from './core/request.ts'; -import type { BackendVersionResponse, BackendUptodateResponse, GetLicenseIdResponse, GetOpenApiYamlResponse, GetAuditLogData, GetAuditLogResponse, ListAuditLogsData, ListAuditLogsResponse, LoginData, LoginResponse, LogoutResponse, GetUserData, GetUserResponse, UpdateUserData, UpdateUserResponse, IsOwnerOfPathData, IsOwnerOfPathResponse, SetPasswordData, SetPasswordResponse, SetPasswordForUserData, SetPasswordForUserResponse, SetLoginTypeForUserData, SetLoginTypeForUserResponse, CreateUserGloballyData, CreateUserGloballyResponse, GlobalUserUpdateData, GlobalUserUpdateResponse, GlobalUsernameInfoData, GlobalUsernameInfoResponse, GlobalUserRenameData, GlobalUserRenameResponse, GlobalUserDeleteData, GlobalUserDeleteResponse, GlobalUsersOverwriteData, GlobalUsersOverwriteResponse, GlobalUsersExportResponse, DeleteUserData, DeleteUserResponse, ListWorkspacesResponse, IsDomainAllowedResponse, ListUserWorkspacesResponse, ListWorkspacesAsSuperAdminData, ListWorkspacesAsSuperAdminResponse, CreateWorkspaceData, CreateWorkspaceResponse, ExistsWorkspaceData, ExistsWorkspaceResponse, ExistsUsernameData, ExistsUsernameResponse, GetGlobalData, GetGlobalResponse, SetGlobalData, SetGlobalResponse, GetLocalResponse, TestSmtpData, TestSmtpResponse, TestCriticalChannelsData, TestCriticalChannelsResponse, GetCriticalAlertsData, GetCriticalAlertsResponse, AcknowledgeCriticalAlertData, AcknowledgeCriticalAlertResponse, AcknowledgeAllCriticalAlertsResponse, TestLicenseKeyData, TestLicenseKeyResponse, TestObjectStorageConfigData, TestObjectStorageConfigResponse, SendStatsResponse, GetLatestKeyRenewalAttemptResponse, RenewLicenseKeyData, RenewLicenseKeyResponse, CreateCustomerPortalSessionData, CreateCustomerPortalSessionResponse, TestMetadataData, TestMetadataResponse, ListGlobalSettingsResponse, GetCurrentEmailResponse, RefreshUserTokenData, RefreshUserTokenResponse, GetTutorialProgressResponse, UpdateTutorialProgressData, UpdateTutorialProgressResponse, LeaveInstanceResponse, GetUsageResponse, GetRunnableResponse, GlobalWhoamiResponse, ListWorkspaceInvitesResponse, WhoamiData, WhoamiResponse, AcceptInviteData, AcceptInviteResponse, DeclineInviteData, DeclineInviteResponse, InviteUserData, InviteUserResponse, AddUserData, AddUserResponse, DeleteInviteData, DeleteInviteResponse, ArchiveWorkspaceData, ArchiveWorkspaceResponse, UnarchiveWorkspaceData, UnarchiveWorkspaceResponse, DeleteWorkspaceData, DeleteWorkspaceResponse, LeaveWorkspaceData, LeaveWorkspaceResponse, GetWorkspaceNameData, GetWorkspaceNameResponse, ChangeWorkspaceNameData, ChangeWorkspaceNameResponse, ChangeWorkspaceIdData, ChangeWorkspaceIdResponse, ChangeWorkspaceColorData, ChangeWorkspaceColorResponse, WhoisData, WhoisResponse, UpdateOperatorSettingsData, UpdateOperatorSettingsResponse, ExistsEmailData, ExistsEmailResponse, ListUsersAsSuperAdminData, ListUsersAsSuperAdminResponse, ListPendingInvitesData, ListPendingInvitesResponse, GetSettingsData, GetSettingsResponse, GetDeployToData, GetDeployToResponse, GetIsPremiumData, GetIsPremiumResponse, GetPremiumInfoData, GetPremiumInfoResponse, SetAutomaticBillingData, SetAutomaticBillingResponse, GetThresholdAlertData, GetThresholdAlertResponse, SetThresholdAlertData, SetThresholdAlertResponse, EditSlackCommandData, EditSlackCommandResponse, RunSlackMessageTestJobData, RunSlackMessageTestJobResponse, EditDeployToData, EditDeployToResponse, EditAutoInviteData, EditAutoInviteResponse, EditWebhookData, EditWebhookResponse, EditCopilotConfigData, EditCopilotConfigResponse, GetCopilotInfoData, GetCopilotInfoResponse, EditErrorHandlerData, EditErrorHandlerResponse, EditLargeFileStorageConfigData, EditLargeFileStorageConfigResponse, EditWorkspaceGitSyncConfigData, EditWorkspaceGitSyncConfigResponse, EditWorkspaceDeployUiSettingsData, EditWorkspaceDeployUiSettingsResponse, EditWorkspaceDefaultAppData, EditWorkspaceDefaultAppResponse, EditDefaultScriptsData, EditDefaultScriptsResponse, GetDefaultScriptsData, GetDefaultScriptsResponse, SetEnvironmentVariableData, SetEnvironmentVariableResponse, GetWorkspaceEncryptionKeyData, GetWorkspaceEncryptionKeyResponse, SetWorkspaceEncryptionKeyData, SetWorkspaceEncryptionKeyResponse, GetWorkspaceDefaultAppData, GetWorkspaceDefaultAppResponse, GetLargeFileStorageConfigData, GetLargeFileStorageConfigResponse, GetWorkspaceUsageData, GetWorkspaceUsageResponse, GetUsedTriggersData, GetUsedTriggersResponse, ListUsersData, ListUsersResponse, ListUsersUsageData, ListUsersUsageResponse, ListUsernamesData, ListUsernamesResponse, UsernameToEmailData, UsernameToEmailResponse, CreateTokenData, CreateTokenResponse, CreateTokenImpersonateData, CreateTokenImpersonateResponse, DeleteTokenData, DeleteTokenResponse, ListTokensData, ListTokensResponse, GetOidcTokenData, GetOidcTokenResponse, CreateVariableData, CreateVariableResponse, EncryptValueData, EncryptValueResponse, DeleteVariableData, DeleteVariableResponse, UpdateVariableData, UpdateVariableResponse, GetVariableData, GetVariableResponse, GetVariableValueData, GetVariableValueResponse, ExistsVariableData, ExistsVariableResponse, ListVariableData, ListVariableResponse, ListContextualVariablesData, ListContextualVariablesResponse, WorkspaceGetCriticalAlertsData, WorkspaceGetCriticalAlertsResponse, WorkspaceAcknowledgeCriticalAlertData, WorkspaceAcknowledgeCriticalAlertResponse, WorkspaceAcknowledgeAllCriticalAlertsData, WorkspaceAcknowledgeAllCriticalAlertsResponse, WorkspaceMuteCriticalAlertsUiData, WorkspaceMuteCriticalAlertsUiResponse, LoginWithOauthData, LoginWithOauthResponse, ConnectSlackCallbackData, ConnectSlackCallbackResponse, ConnectSlackCallbackInstanceData, ConnectSlackCallbackInstanceResponse, ConnectCallbackData, ConnectCallbackResponse, CreateAccountData, CreateAccountResponse, RefreshTokenData, RefreshTokenResponse, DisconnectAccountData, DisconnectAccountResponse, DisconnectSlackData, DisconnectSlackResponse, ListOauthLoginsResponse, ListOauthConnectsResponse, GetOauthConnectData, GetOauthConnectResponse, SyncTeamsResponse, CreateResourceData, CreateResourceResponse, DeleteResourceData, DeleteResourceResponse, UpdateResourceData, UpdateResourceResponse, UpdateResourceValueData, UpdateResourceValueResponse, GetResourceData, GetResourceResponse, GetResourceValueInterpolatedData, GetResourceValueInterpolatedResponse, GetResourceValueData, GetResourceValueResponse, ExistsResourceData, ExistsResourceResponse, ListResourceData, ListResourceResponse, ListSearchResourceData, ListSearchResourceResponse, ListResourceNamesData, ListResourceNamesResponse, CreateResourceTypeData, CreateResourceTypeResponse, FileResourceTypeToFileExtMapData, FileResourceTypeToFileExtMapResponse, DeleteResourceTypeData, DeleteResourceTypeResponse, UpdateResourceTypeData, UpdateResourceTypeResponse, GetResourceTypeData, GetResourceTypeResponse, ExistsResourceTypeData, ExistsResourceTypeResponse, ListResourceTypeData, ListResourceTypeResponse, ListResourceTypeNamesData, ListResourceTypeNamesResponse, QueryResourceTypesData, QueryResourceTypesResponse, ListHubIntegrationsData, ListHubIntegrationsResponse, ListHubFlowsResponse, GetHubFlowByIdData, GetHubFlowByIdResponse, ListHubAppsResponse, GetHubAppByIdData, GetHubAppByIdResponse, GetPublicAppByCustomPathData, GetPublicAppByCustomPathResponse, GetHubScriptContentByPathData, GetHubScriptContentByPathResponse, GetHubScriptByPathData, GetHubScriptByPathResponse, GetTopHubScriptsData, GetTopHubScriptsResponse, QueryHubScriptsData, QueryHubScriptsResponse, ListSearchScriptData, ListSearchScriptResponse, ListScriptsData, ListScriptsResponse, ListScriptPathsData, ListScriptPathsResponse, CreateDraftData, CreateDraftResponse, DeleteDraftData, DeleteDraftResponse, CreateScriptData, CreateScriptResponse, ToggleWorkspaceErrorHandlerForScriptData, ToggleWorkspaceErrorHandlerForScriptResponse, GetCustomTagsData, GetCustomTagsResponse, GeDefaultTagsResponse, IsDefaultTagsPerWorkspaceResponse, ArchiveScriptByPathData, ArchiveScriptByPathResponse, ArchiveScriptByHashData, ArchiveScriptByHashResponse, DeleteScriptByHashData, DeleteScriptByHashResponse, DeleteScriptByPathData, DeleteScriptByPathResponse, GetScriptByPathData, GetScriptByPathResponse, GetTriggersCountOfScriptData, GetTriggersCountOfScriptResponse, ListTokensOfScriptData, ListTokensOfScriptResponse, GetScriptByPathWithDraftData, GetScriptByPathWithDraftResponse, GetScriptHistoryByPathData, GetScriptHistoryByPathResponse, GetScriptLatestVersionData, GetScriptLatestVersionResponse, UpdateScriptHistoryData, UpdateScriptHistoryResponse, RawScriptByPathData, RawScriptByPathResponse, RawScriptByPathTokenedData, RawScriptByPathTokenedResponse, ExistsScriptByPathData, ExistsScriptByPathResponse, GetScriptByHashData, GetScriptByHashResponse, RawScriptByHashData, RawScriptByHashResponse, GetScriptDeploymentStatusData, GetScriptDeploymentStatusResponse, RunScriptByPathData, RunScriptByPathResponse, OpenaiSyncScriptByPathData, OpenaiSyncScriptByPathResponse, RunWaitResultScriptByPathData, RunWaitResultScriptByPathResponse, RunWaitResultScriptByPathGetData, RunWaitResultScriptByPathGetResponse, OpenaiSyncFlowByPathData, OpenaiSyncFlowByPathResponse, RunWaitResultFlowByPathData, RunWaitResultFlowByPathResponse, ResultByIdData, ResultByIdResponse, ListFlowPathsData, ListFlowPathsResponse, ListSearchFlowData, ListSearchFlowResponse, ListFlowsData, ListFlowsResponse, GetFlowHistoryData, GetFlowHistoryResponse, GetFlowLatestVersionData, GetFlowLatestVersionResponse, GetFlowVersionData, GetFlowVersionResponse, UpdateFlowHistoryData, UpdateFlowHistoryResponse, GetFlowByPathData, GetFlowByPathResponse, GetTriggersCountOfFlowData, GetTriggersCountOfFlowResponse, ListTokensOfFlowData, ListTokensOfFlowResponse, ToggleWorkspaceErrorHandlerForFlowData, ToggleWorkspaceErrorHandlerForFlowResponse, GetFlowByPathWithDraftData, GetFlowByPathWithDraftResponse, ExistsFlowByPathData, ExistsFlowByPathResponse, CreateFlowData, CreateFlowResponse, UpdateFlowData, UpdateFlowResponse, ArchiveFlowByPathData, ArchiveFlowByPathResponse, DeleteFlowByPathData, DeleteFlowByPathResponse, ListRawAppsData, ListRawAppsResponse, ExistsRawAppData, ExistsRawAppResponse, GetRawAppDataData, GetRawAppDataResponse, ListSearchAppData, ListSearchAppResponse, ListAppsData, ListAppsResponse, CreateAppData, CreateAppResponse, ExistsAppData, ExistsAppResponse, GetAppByPathData, GetAppByPathResponse, GetAppLiteByPathData, GetAppLiteByPathResponse, GetAppByPathWithDraftData, GetAppByPathWithDraftResponse, GetAppHistoryByPathData, GetAppHistoryByPathResponse, GetAppLatestVersionData, GetAppLatestVersionResponse, UpdateAppHistoryData, UpdateAppHistoryResponse, GetPublicAppBySecretData, GetPublicAppBySecretResponse, GetPublicResourceData, GetPublicResourceResponse, GetPublicSecretOfAppData, GetPublicSecretOfAppResponse, GetAppByVersionData, GetAppByVersionResponse, CreateRawAppData, CreateRawAppResponse, UpdateRawAppData, UpdateRawAppResponse, DeleteRawAppData, DeleteRawAppResponse, DeleteAppData, DeleteAppResponse, UpdateAppData, UpdateAppResponse, CustomPathExistsData, CustomPathExistsResponse, ExecuteComponentData, ExecuteComponentResponse, RunFlowByPathData, RunFlowByPathResponse, RestartFlowAtStepData, RestartFlowAtStepResponse, RunScriptByHashData, RunScriptByHashResponse, RunScriptPreviewData, RunScriptPreviewResponse, RunCodeWorkflowTaskData, RunCodeWorkflowTaskResponse, RunRawScriptDependenciesData, RunRawScriptDependenciesResponse, RunFlowPreviewData, RunFlowPreviewResponse, ListQueueData, ListQueueResponse, GetQueueCountData, GetQueueCountResponse, GetCompletedCountData, GetCompletedCountResponse, CountCompletedJobsData, CountCompletedJobsResponse, ListFilteredUuidsData, ListFilteredUuidsResponse, CancelSelectionData, CancelSelectionResponse, ListCompletedJobsData, ListCompletedJobsResponse, ListJobsData, ListJobsResponse, GetDbClockResponse, CountJobsByTagData, CountJobsByTagResponse, GetJobData, GetJobResponse, GetRootJobIdData, GetRootJobIdResponse, GetJobLogsData, GetJobLogsResponse, GetJobArgsData, GetJobArgsResponse, GetJobUpdatesData, GetJobUpdatesResponse, GetLogFileFromStoreData, GetLogFileFromStoreResponse, GetFlowDebugInfoData, GetFlowDebugInfoResponse, GetCompletedJobData, GetCompletedJobResponse, GetCompletedJobResultData, GetCompletedJobResultResponse, GetCompletedJobResultMaybeData, GetCompletedJobResultMaybeResponse, DeleteCompletedJobData, DeleteCompletedJobResponse, CancelQueuedJobData, CancelQueuedJobResponse, CancelPersistentQueuedJobsData, CancelPersistentQueuedJobsResponse, ForceCancelQueuedJobData, ForceCancelQueuedJobResponse, CreateJobSignatureData, CreateJobSignatureResponse, GetResumeUrlsData, GetResumeUrlsResponse, GetSlackApprovalPayloadData, GetSlackApprovalPayloadResponse, ResumeSuspendedJobGetData, ResumeSuspendedJobGetResponse, ResumeSuspendedJobPostData, ResumeSuspendedJobPostResponse, SetFlowUserStateData, SetFlowUserStateResponse, GetFlowUserStateData, GetFlowUserStateResponse, ResumeSuspendedFlowAsOwnerData, ResumeSuspendedFlowAsOwnerResponse, CancelSuspendedJobGetData, CancelSuspendedJobGetResponse, CancelSuspendedJobPostData, CancelSuspendedJobPostResponse, GetSuspendedJobFlowData, GetSuspendedJobFlowResponse, PreviewScheduleData, PreviewScheduleResponse, CreateScheduleData, CreateScheduleResponse, UpdateScheduleData, UpdateScheduleResponse, SetScheduleEnabledData, SetScheduleEnabledResponse, DeleteScheduleData, DeleteScheduleResponse, GetScheduleData, GetScheduleResponse, ExistsScheduleData, ExistsScheduleResponse, ListSchedulesData, ListSchedulesResponse, ListSchedulesWithJobsData, ListSchedulesWithJobsResponse, SetDefaultErrorOrRecoveryHandlerData, SetDefaultErrorOrRecoveryHandlerResponse, CreateHttpTriggerData, CreateHttpTriggerResponse, UpdateHttpTriggerData, UpdateHttpTriggerResponse, DeleteHttpTriggerData, DeleteHttpTriggerResponse, GetHttpTriggerData, GetHttpTriggerResponse, ListHttpTriggersData, ListHttpTriggersResponse, ExistsHttpTriggerData, ExistsHttpTriggerResponse, ExistsRouteData, ExistsRouteResponse, CreateWebsocketTriggerData, CreateWebsocketTriggerResponse, UpdateWebsocketTriggerData, UpdateWebsocketTriggerResponse, DeleteWebsocketTriggerData, DeleteWebsocketTriggerResponse, GetWebsocketTriggerData, GetWebsocketTriggerResponse, ListWebsocketTriggersData, ListWebsocketTriggersResponse, ExistsWebsocketTriggerData, ExistsWebsocketTriggerResponse, SetWebsocketTriggerEnabledData, SetWebsocketTriggerEnabledResponse, TestWebsocketConnectionData, TestWebsocketConnectionResponse, CreateKafkaTriggerData, CreateKafkaTriggerResponse, UpdateKafkaTriggerData, UpdateKafkaTriggerResponse, DeleteKafkaTriggerData, DeleteKafkaTriggerResponse, GetKafkaTriggerData, GetKafkaTriggerResponse, ListKafkaTriggersData, ListKafkaTriggersResponse, ExistsKafkaTriggerData, ExistsKafkaTriggerResponse, SetKafkaTriggerEnabledData, SetKafkaTriggerEnabledResponse, TestKafkaConnectionData, TestKafkaConnectionResponse, CreateNatsTriggerData, CreateNatsTriggerResponse, UpdateNatsTriggerData, UpdateNatsTriggerResponse, DeleteNatsTriggerData, DeleteNatsTriggerResponse, GetNatsTriggerData, GetNatsTriggerResponse, ListNatsTriggersData, ListNatsTriggersResponse, ExistsNatsTriggerData, ExistsNatsTriggerResponse, SetNatsTriggerEnabledData, SetNatsTriggerEnabledResponse, TestNatsConnectionData, TestNatsConnectionResponse, IsValidPostgresConfigurationData, IsValidPostgresConfigurationResponse, CreateTemplateScriptData, CreateTemplateScriptResponse, GetTemplateScriptData, GetTemplateScriptResponse, ListPostgresReplicationSlotData, ListPostgresReplicationSlotResponse, CreatePostgresReplicationSlotData, CreatePostgresReplicationSlotResponse, DeletePostgresReplicationSlotData, DeletePostgresReplicationSlotResponse, ListPostgresPublicationData, ListPostgresPublicationResponse, GetPostgresPublicationData, GetPostgresPublicationResponse, CreatePostgresPublicationData, CreatePostgresPublicationResponse, UpdatePostgresPublicationData, UpdatePostgresPublicationResponse, DeletePostgresPublicationData, DeletePostgresPublicationResponse, CreatePostgresTriggerData, CreatePostgresTriggerResponse, UpdatePostgresTriggerData, UpdatePostgresTriggerResponse, DeletePostgresTriggerData, DeletePostgresTriggerResponse, GetPostgresTriggerData, GetPostgresTriggerResponse, ListPostgresTriggersData, ListPostgresTriggersResponse, ExistsPostgresTriggerData, ExistsPostgresTriggerResponse, SetPostgresTriggerEnabledData, SetPostgresTriggerEnabledResponse, ListInstanceGroupsResponse, GetInstanceGroupData, GetInstanceGroupResponse, CreateInstanceGroupData, CreateInstanceGroupResponse, UpdateInstanceGroupData, UpdateInstanceGroupResponse, DeleteInstanceGroupData, DeleteInstanceGroupResponse, AddUserToInstanceGroupData, AddUserToInstanceGroupResponse, RemoveUserFromInstanceGroupData, RemoveUserFromInstanceGroupResponse, ExportInstanceGroupsResponse, OverwriteInstanceGroupsData, OverwriteInstanceGroupsResponse, ListGroupsData, ListGroupsResponse, ListGroupNamesData, ListGroupNamesResponse, CreateGroupData, CreateGroupResponse, UpdateGroupData, UpdateGroupResponse, DeleteGroupData, DeleteGroupResponse, GetGroupData, GetGroupResponse, AddUserToGroupData, AddUserToGroupResponse, RemoveUserToGroupData, RemoveUserToGroupResponse, ListFoldersData, ListFoldersResponse, ListFolderNamesData, ListFolderNamesResponse, CreateFolderData, CreateFolderResponse, UpdateFolderData, UpdateFolderResponse, DeleteFolderData, DeleteFolderResponse, GetFolderData, GetFolderResponse, GetFolderUsageData, GetFolderUsageResponse, AddOwnerToFolderData, AddOwnerToFolderResponse, RemoveOwnerToFolderData, RemoveOwnerToFolderResponse, ListWorkersData, ListWorkersResponse, ExistsWorkerWithTagData, ExistsWorkerWithTagResponse, GetQueueMetricsResponse, GetCountsOfJobsWaitingPerTagResponse, ListWorkerGroupsResponse, GetConfigData, GetConfigResponse, UpdateConfigData, UpdateConfigResponse, DeleteConfigData, DeleteConfigResponse, ListConfigsResponse, ListAutoscalingEventsData, ListAutoscalingEventsResponse, GetGranularAclsData, GetGranularAclsResponse, AddGranularAclsData, AddGranularAclsResponse, RemoveGranularAclsData, RemoveGranularAclsResponse, SetCaptureConfigData, SetCaptureConfigResponse, PingCaptureConfigData, PingCaptureConfigResponse, GetCaptureConfigsData, GetCaptureConfigsResponse, ListCapturesData, ListCapturesResponse, GetCaptureData, GetCaptureResponse, DeleteCaptureData, DeleteCaptureResponse, StarData, StarResponse, UnstarData, UnstarResponse, GetInputHistoryData, GetInputHistoryResponse, GetArgsFromHistoryOrSavedInputData, GetArgsFromHistoryOrSavedInputResponse, ListInputsData, ListInputsResponse, CreateInputData, CreateInputResponse, UpdateInputData, UpdateInputResponse, DeleteInputData, DeleteInputResponse, DuckdbConnectionSettingsData, DuckdbConnectionSettingsResponse, DuckdbConnectionSettingsV2Data, DuckdbConnectionSettingsV2Response, PolarsConnectionSettingsData, PolarsConnectionSettingsResponse, PolarsConnectionSettingsV2Data, PolarsConnectionSettingsV2Response, S3ResourceInfoData, S3ResourceInfoResponse, DatasetStorageTestConnectionData, DatasetStorageTestConnectionResponse, ListStoredFilesData, ListStoredFilesResponse, LoadFileMetadataData, LoadFileMetadataResponse, LoadFilePreviewData, LoadFilePreviewResponse, LoadParquetPreviewData, LoadParquetPreviewResponse, LoadTableRowCountData, LoadTableRowCountResponse, LoadCsvPreviewData, LoadCsvPreviewResponse, DeleteS3FileData, DeleteS3FileResponse, MoveS3FileData, MoveS3FileResponse, FileUploadData, FileUploadResponse, FileDownloadData, FileDownloadResponse, FileDownloadParquetAsCsvData, FileDownloadParquetAsCsvResponse, GetJobMetricsData, GetJobMetricsResponse, SetJobProgressData, SetJobProgressResponse, GetJobProgressData, GetJobProgressResponse, ListLogFilesData, ListLogFilesResponse, GetLogFileData, GetLogFileResponse, ListConcurrencyGroupsResponse, DeleteConcurrencyGroupData, DeleteConcurrencyGroupResponse, GetConcurrencyKeyData, GetConcurrencyKeyResponse, ListExtendedJobsData, ListExtendedJobsResponse, SearchJobsIndexData, SearchJobsIndexResponse, SearchLogsIndexData, SearchLogsIndexResponse, CountSearchLogsIndexData, CountSearchLogsIndexResponse, ClearIndexData, ClearIndexResponse } from './types.gen.ts'; +import type { BackendVersionResponse, BackendUptodateResponse, GetLicenseIdResponse, GetOpenApiYamlResponse, GetAuditLogData, GetAuditLogResponse, ListAuditLogsData, ListAuditLogsResponse, LoginData, LoginResponse, LogoutResponse, GetUserData, GetUserResponse, UpdateUserData, UpdateUserResponse, IsOwnerOfPathData, IsOwnerOfPathResponse, SetPasswordData, SetPasswordResponse, SetPasswordForUserData, SetPasswordForUserResponse, SetLoginTypeForUserData, SetLoginTypeForUserResponse, CreateUserGloballyData, CreateUserGloballyResponse, GlobalUserUpdateData, GlobalUserUpdateResponse, GlobalUsernameInfoData, GlobalUsernameInfoResponse, GlobalUserRenameData, GlobalUserRenameResponse, GlobalUserDeleteData, GlobalUserDeleteResponse, GlobalUsersOverwriteData, GlobalUsersOverwriteResponse, GlobalUsersExportResponse, DeleteUserData, DeleteUserResponse, ListWorkspacesResponse, IsDomainAllowedResponse, ListUserWorkspacesResponse, ListWorkspacesAsSuperAdminData, ListWorkspacesAsSuperAdminResponse, CreateWorkspaceData, CreateWorkspaceResponse, ExistsWorkspaceData, ExistsWorkspaceResponse, ExistsUsernameData, ExistsUsernameResponse, GetGlobalData, GetGlobalResponse, SetGlobalData, SetGlobalResponse, GetLocalResponse, TestSmtpData, TestSmtpResponse, TestCriticalChannelsData, TestCriticalChannelsResponse, GetCriticalAlertsData, GetCriticalAlertsResponse, AcknowledgeCriticalAlertData, AcknowledgeCriticalAlertResponse, AcknowledgeAllCriticalAlertsResponse, TestLicenseKeyData, TestLicenseKeyResponse, TestObjectStorageConfigData, TestObjectStorageConfigResponse, SendStatsResponse, GetLatestKeyRenewalAttemptResponse, RenewLicenseKeyData, RenewLicenseKeyResponse, CreateCustomerPortalSessionData, CreateCustomerPortalSessionResponse, TestMetadataData, TestMetadataResponse, ListGlobalSettingsResponse, GetCurrentEmailResponse, RefreshUserTokenData, RefreshUserTokenResponse, GetTutorialProgressResponse, UpdateTutorialProgressData, UpdateTutorialProgressResponse, LeaveInstanceResponse, GetUsageResponse, GetRunnableResponse, GlobalWhoamiResponse, ListWorkspaceInvitesResponse, WhoamiData, WhoamiResponse, AcceptInviteData, AcceptInviteResponse, DeclineInviteData, DeclineInviteResponse, InviteUserData, InviteUserResponse, AddUserData, AddUserResponse, DeleteInviteData, DeleteInviteResponse, ArchiveWorkspaceData, ArchiveWorkspaceResponse, UnarchiveWorkspaceData, UnarchiveWorkspaceResponse, DeleteWorkspaceData, DeleteWorkspaceResponse, LeaveWorkspaceData, LeaveWorkspaceResponse, GetWorkspaceNameData, GetWorkspaceNameResponse, ChangeWorkspaceNameData, ChangeWorkspaceNameResponse, ChangeWorkspaceIdData, ChangeWorkspaceIdResponse, ChangeWorkspaceColorData, ChangeWorkspaceColorResponse, WhoisData, WhoisResponse, UpdateOperatorSettingsData, UpdateOperatorSettingsResponse, ExistsEmailData, ExistsEmailResponse, ListUsersAsSuperAdminData, ListUsersAsSuperAdminResponse, ListPendingInvitesData, ListPendingInvitesResponse, GetSettingsData, GetSettingsResponse, GetDeployToData, GetDeployToResponse, GetIsPremiumData, GetIsPremiumResponse, GetPremiumInfoData, GetPremiumInfoResponse, SetAutomaticBillingData, SetAutomaticBillingResponse, GetThresholdAlertData, GetThresholdAlertResponse, SetThresholdAlertData, SetThresholdAlertResponse, EditSlackCommandData, EditSlackCommandResponse, RunSlackMessageTestJobData, RunSlackMessageTestJobResponse, EditDeployToData, EditDeployToResponse, EditAutoInviteData, EditAutoInviteResponse, EditWebhookData, EditWebhookResponse, EditCopilotConfigData, EditCopilotConfigResponse, GetCopilotInfoData, GetCopilotInfoResponse, EditErrorHandlerData, EditErrorHandlerResponse, EditLargeFileStorageConfigData, EditLargeFileStorageConfigResponse, EditWorkspaceGitSyncConfigData, EditWorkspaceGitSyncConfigResponse, EditWorkspaceDeployUiSettingsData, EditWorkspaceDeployUiSettingsResponse, EditWorkspaceDefaultAppData, EditWorkspaceDefaultAppResponse, EditDefaultScriptsData, EditDefaultScriptsResponse, GetDefaultScriptsData, GetDefaultScriptsResponse, SetEnvironmentVariableData, SetEnvironmentVariableResponse, GetWorkspaceEncryptionKeyData, GetWorkspaceEncryptionKeyResponse, SetWorkspaceEncryptionKeyData, SetWorkspaceEncryptionKeyResponse, GetWorkspaceDefaultAppData, GetWorkspaceDefaultAppResponse, GetLargeFileStorageConfigData, GetLargeFileStorageConfigResponse, GetWorkspaceUsageData, GetWorkspaceUsageResponse, GetUsedTriggersData, GetUsedTriggersResponse, ListUsersData, ListUsersResponse, ListUsersUsageData, ListUsersUsageResponse, ListUsernamesData, ListUsernamesResponse, UsernameToEmailData, UsernameToEmailResponse, CreateTokenData, CreateTokenResponse, CreateTokenImpersonateData, CreateTokenImpersonateResponse, DeleteTokenData, DeleteTokenResponse, ListTokensData, ListTokensResponse, GetOidcTokenData, GetOidcTokenResponse, CreateVariableData, CreateVariableResponse, EncryptValueData, EncryptValueResponse, DeleteVariableData, DeleteVariableResponse, UpdateVariableData, UpdateVariableResponse, GetVariableData, GetVariableResponse, GetVariableValueData, GetVariableValueResponse, ExistsVariableData, ExistsVariableResponse, ListVariableData, ListVariableResponse, ListContextualVariablesData, ListContextualVariablesResponse, WorkspaceGetCriticalAlertsData, WorkspaceGetCriticalAlertsResponse, WorkspaceAcknowledgeCriticalAlertData, WorkspaceAcknowledgeCriticalAlertResponse, WorkspaceAcknowledgeAllCriticalAlertsData, WorkspaceAcknowledgeAllCriticalAlertsResponse, WorkspaceMuteCriticalAlertsUiData, WorkspaceMuteCriticalAlertsUiResponse, LoginWithOauthData, LoginWithOauthResponse, ConnectSlackCallbackData, ConnectSlackCallbackResponse, ConnectSlackCallbackInstanceData, ConnectSlackCallbackInstanceResponse, ConnectCallbackData, ConnectCallbackResponse, CreateAccountData, CreateAccountResponse, RefreshTokenData, RefreshTokenResponse, DisconnectAccountData, DisconnectAccountResponse, DisconnectSlackData, DisconnectSlackResponse, ListOauthLoginsResponse, ListOauthConnectsResponse, GetOauthConnectData, GetOauthConnectResponse, SyncTeamsResponse, CreateResourceData, CreateResourceResponse, DeleteResourceData, DeleteResourceResponse, UpdateResourceData, UpdateResourceResponse, UpdateResourceValueData, UpdateResourceValueResponse, GetResourceData, GetResourceResponse, GetResourceValueInterpolatedData, GetResourceValueInterpolatedResponse, GetResourceValueData, GetResourceValueResponse, ExistsResourceData, ExistsResourceResponse, ListResourceData, ListResourceResponse, ListSearchResourceData, ListSearchResourceResponse, ListResourceNamesData, ListResourceNamesResponse, CreateResourceTypeData, CreateResourceTypeResponse, FileResourceTypeToFileExtMapData, FileResourceTypeToFileExtMapResponse, DeleteResourceTypeData, DeleteResourceTypeResponse, UpdateResourceTypeData, UpdateResourceTypeResponse, GetResourceTypeData, GetResourceTypeResponse, ExistsResourceTypeData, ExistsResourceTypeResponse, ListResourceTypeData, ListResourceTypeResponse, ListResourceTypeNamesData, ListResourceTypeNamesResponse, QueryResourceTypesData, QueryResourceTypesResponse, ListHubIntegrationsData, ListHubIntegrationsResponse, ListHubFlowsResponse, GetHubFlowByIdData, GetHubFlowByIdResponse, ListHubAppsResponse, GetHubAppByIdData, GetHubAppByIdResponse, GetPublicAppByCustomPathData, GetPublicAppByCustomPathResponse, GetHubScriptContentByPathData, GetHubScriptContentByPathResponse, GetHubScriptByPathData, GetHubScriptByPathResponse, GetTopHubScriptsData, GetTopHubScriptsResponse, QueryHubScriptsData, QueryHubScriptsResponse, ListSearchScriptData, ListSearchScriptResponse, ListScriptsData, ListScriptsResponse, ListScriptPathsData, ListScriptPathsResponse, CreateDraftData, CreateDraftResponse, DeleteDraftData, DeleteDraftResponse, CreateScriptData, CreateScriptResponse, ToggleWorkspaceErrorHandlerForScriptData, ToggleWorkspaceErrorHandlerForScriptResponse, GetCustomTagsData, GetCustomTagsResponse, GeDefaultTagsResponse, IsDefaultTagsPerWorkspaceResponse, ArchiveScriptByPathData, ArchiveScriptByPathResponse, ArchiveScriptByHashData, ArchiveScriptByHashResponse, DeleteScriptByHashData, DeleteScriptByHashResponse, DeleteScriptByPathData, DeleteScriptByPathResponse, GetScriptByPathData, GetScriptByPathResponse, GetTriggersCountOfScriptData, GetTriggersCountOfScriptResponse, ListTokensOfScriptData, ListTokensOfScriptResponse, GetScriptByPathWithDraftData, GetScriptByPathWithDraftResponse, GetScriptHistoryByPathData, GetScriptHistoryByPathResponse, GetScriptLatestVersionData, GetScriptLatestVersionResponse, UpdateScriptHistoryData, UpdateScriptHistoryResponse, RawScriptByPathData, RawScriptByPathResponse, RawScriptByPathTokenedData, RawScriptByPathTokenedResponse, ExistsScriptByPathData, ExistsScriptByPathResponse, GetScriptByHashData, GetScriptByHashResponse, RawScriptByHashData, RawScriptByHashResponse, GetScriptDeploymentStatusData, GetScriptDeploymentStatusResponse, RunScriptByPathData, RunScriptByPathResponse, OpenaiSyncScriptByPathData, OpenaiSyncScriptByPathResponse, RunWaitResultScriptByPathData, RunWaitResultScriptByPathResponse, RunWaitResultScriptByPathGetData, RunWaitResultScriptByPathGetResponse, OpenaiSyncFlowByPathData, OpenaiSyncFlowByPathResponse, RunWaitResultFlowByPathData, RunWaitResultFlowByPathResponse, ResultByIdData, ResultByIdResponse, ListFlowPathsData, ListFlowPathsResponse, ListSearchFlowData, ListSearchFlowResponse, ListFlowsData, ListFlowsResponse, GetFlowHistoryData, GetFlowHistoryResponse, GetFlowLatestVersionData, GetFlowLatestVersionResponse, GetFlowVersionData, GetFlowVersionResponse, UpdateFlowHistoryData, UpdateFlowHistoryResponse, GetFlowByPathData, GetFlowByPathResponse, GetTriggersCountOfFlowData, GetTriggersCountOfFlowResponse, ListTokensOfFlowData, ListTokensOfFlowResponse, ToggleWorkspaceErrorHandlerForFlowData, ToggleWorkspaceErrorHandlerForFlowResponse, GetFlowByPathWithDraftData, GetFlowByPathWithDraftResponse, ExistsFlowByPathData, ExistsFlowByPathResponse, CreateFlowData, CreateFlowResponse, UpdateFlowData, UpdateFlowResponse, ArchiveFlowByPathData, ArchiveFlowByPathResponse, DeleteFlowByPathData, DeleteFlowByPathResponse, ListRawAppsData, ListRawAppsResponse, ExistsRawAppData, ExistsRawAppResponse, GetRawAppDataData, GetRawAppDataResponse, ListSearchAppData, ListSearchAppResponse, ListAppsData, ListAppsResponse, CreateAppData, CreateAppResponse, ExistsAppData, ExistsAppResponse, GetAppByPathData, GetAppByPathResponse, GetAppLiteByPathData, GetAppLiteByPathResponse, GetAppByPathWithDraftData, GetAppByPathWithDraftResponse, GetAppHistoryByPathData, GetAppHistoryByPathResponse, GetAppLatestVersionData, GetAppLatestVersionResponse, UpdateAppHistoryData, UpdateAppHistoryResponse, GetPublicAppBySecretData, GetPublicAppBySecretResponse, GetPublicResourceData, GetPublicResourceResponse, GetPublicSecretOfAppData, GetPublicSecretOfAppResponse, GetAppByVersionData, GetAppByVersionResponse, CreateRawAppData, CreateRawAppResponse, UpdateRawAppData, UpdateRawAppResponse, DeleteRawAppData, DeleteRawAppResponse, DeleteAppData, DeleteAppResponse, UpdateAppData, UpdateAppResponse, CustomPathExistsData, CustomPathExistsResponse, ExecuteComponentData, ExecuteComponentResponse, RunFlowByPathData, RunFlowByPathResponse, RestartFlowAtStepData, RestartFlowAtStepResponse, RunScriptByHashData, RunScriptByHashResponse, RunScriptPreviewData, RunScriptPreviewResponse, RunCodeWorkflowTaskData, RunCodeWorkflowTaskResponse, RunRawScriptDependenciesData, RunRawScriptDependenciesResponse, RunFlowPreviewData, RunFlowPreviewResponse, ListQueueData, ListQueueResponse, GetQueueCountData, GetQueueCountResponse, GetCompletedCountData, GetCompletedCountResponse, CountCompletedJobsData, CountCompletedJobsResponse, ListFilteredUuidsData, ListFilteredUuidsResponse, CancelSelectionData, CancelSelectionResponse, ListCompletedJobsData, ListCompletedJobsResponse, ListJobsData, ListJobsResponse, GetDbClockResponse, CountJobsByTagData, CountJobsByTagResponse, GetJobData, GetJobResponse, GetRootJobIdData, GetRootJobIdResponse, GetJobLogsData, GetJobLogsResponse, GetJobArgsData, GetJobArgsResponse, GetJobUpdatesData, GetJobUpdatesResponse, GetLogFileFromStoreData, GetLogFileFromStoreResponse, GetFlowDebugInfoData, GetFlowDebugInfoResponse, GetCompletedJobData, GetCompletedJobResponse, GetCompletedJobResultData, GetCompletedJobResultResponse, GetCompletedJobResultMaybeData, GetCompletedJobResultMaybeResponse, DeleteCompletedJobData, DeleteCompletedJobResponse, CancelQueuedJobData, CancelQueuedJobResponse, CancelPersistentQueuedJobsData, CancelPersistentQueuedJobsResponse, ForceCancelQueuedJobData, ForceCancelQueuedJobResponse, CreateJobSignatureData, CreateJobSignatureResponse, GetResumeUrlsData, GetResumeUrlsResponse, GetSlackApprovalPayloadData, GetSlackApprovalPayloadResponse, ResumeSuspendedJobGetData, ResumeSuspendedJobGetResponse, ResumeSuspendedJobPostData, ResumeSuspendedJobPostResponse, SetFlowUserStateData, SetFlowUserStateResponse, GetFlowUserStateData, GetFlowUserStateResponse, ResumeSuspendedFlowAsOwnerData, ResumeSuspendedFlowAsOwnerResponse, CancelSuspendedJobGetData, CancelSuspendedJobGetResponse, CancelSuspendedJobPostData, CancelSuspendedJobPostResponse, GetSuspendedJobFlowData, GetSuspendedJobFlowResponse, PreviewScheduleData, PreviewScheduleResponse, CreateScheduleData, CreateScheduleResponse, UpdateScheduleData, UpdateScheduleResponse, SetScheduleEnabledData, SetScheduleEnabledResponse, DeleteScheduleData, DeleteScheduleResponse, GetScheduleData, GetScheduleResponse, ExistsScheduleData, ExistsScheduleResponse, ListSchedulesData, ListSchedulesResponse, ListSchedulesWithJobsData, ListSchedulesWithJobsResponse, SetDefaultErrorOrRecoveryHandlerData, SetDefaultErrorOrRecoveryHandlerResponse, CreateHttpTriggerData, CreateHttpTriggerResponse, UpdateHttpTriggerData, UpdateHttpTriggerResponse, DeleteHttpTriggerData, DeleteHttpTriggerResponse, GetHttpTriggerData, GetHttpTriggerResponse, ListHttpTriggersData, ListHttpTriggersResponse, ExistsHttpTriggerData, ExistsHttpTriggerResponse, ExistsRouteData, ExistsRouteResponse, CreateWebsocketTriggerData, CreateWebsocketTriggerResponse, UpdateWebsocketTriggerData, UpdateWebsocketTriggerResponse, DeleteWebsocketTriggerData, DeleteWebsocketTriggerResponse, GetWebsocketTriggerData, GetWebsocketTriggerResponse, ListWebsocketTriggersData, ListWebsocketTriggersResponse, ExistsWebsocketTriggerData, ExistsWebsocketTriggerResponse, SetWebsocketTriggerEnabledData, SetWebsocketTriggerEnabledResponse, TestWebsocketConnectionData, TestWebsocketConnectionResponse, CreateKafkaTriggerData, CreateKafkaTriggerResponse, UpdateKafkaTriggerData, UpdateKafkaTriggerResponse, DeleteKafkaTriggerData, DeleteKafkaTriggerResponse, GetKafkaTriggerData, GetKafkaTriggerResponse, ListKafkaTriggersData, ListKafkaTriggersResponse, ExistsKafkaTriggerData, ExistsKafkaTriggerResponse, SetKafkaTriggerEnabledData, SetKafkaTriggerEnabledResponse, TestKafkaConnectionData, TestKafkaConnectionResponse, CreateNatsTriggerData, CreateNatsTriggerResponse, UpdateNatsTriggerData, UpdateNatsTriggerResponse, DeleteNatsTriggerData, DeleteNatsTriggerResponse, GetNatsTriggerData, GetNatsTriggerResponse, ListNatsTriggersData, ListNatsTriggersResponse, ExistsNatsTriggerData, ExistsNatsTriggerResponse, SetNatsTriggerEnabledData, SetNatsTriggerEnabledResponse, TestNatsConnectionData, TestNatsConnectionResponse, CreateSqsTriggerData, CreateSqsTriggerResponse, UpdateSqsTriggerData, UpdateSqsTriggerResponse, DeleteSqsTriggerData, DeleteSqsTriggerResponse, GetSqsTriggerData, GetSqsTriggerResponse, ListSqsTriggersData, ListSqsTriggersResponse, ExistsSqsTriggerData, ExistsSqsTriggerResponse, SetSqsTriggerEnabledData, SetSqsTriggerEnabledResponse, TestSqsConnectionData, TestSqsConnectionResponse, IsValidPostgresConfigurationData, IsValidPostgresConfigurationResponse, CreateTemplateScriptData, CreateTemplateScriptResponse, GetTemplateScriptData, GetTemplateScriptResponse, ListPostgresReplicationSlotData, ListPostgresReplicationSlotResponse, CreatePostgresReplicationSlotData, CreatePostgresReplicationSlotResponse, DeletePostgresReplicationSlotData, DeletePostgresReplicationSlotResponse, ListPostgresPublicationData, ListPostgresPublicationResponse, GetPostgresPublicationData, GetPostgresPublicationResponse, CreatePostgresPublicationData, CreatePostgresPublicationResponse, UpdatePostgresPublicationData, UpdatePostgresPublicationResponse, DeletePostgresPublicationData, DeletePostgresPublicationResponse, CreatePostgresTriggerData, CreatePostgresTriggerResponse, UpdatePostgresTriggerData, UpdatePostgresTriggerResponse, DeletePostgresTriggerData, DeletePostgresTriggerResponse, GetPostgresTriggerData, GetPostgresTriggerResponse, ListPostgresTriggersData, ListPostgresTriggersResponse, ExistsPostgresTriggerData, ExistsPostgresTriggerResponse, SetPostgresTriggerEnabledData, SetPostgresTriggerEnabledResponse, TestPostgresConnectionData, TestPostgresConnectionResponse, ListInstanceGroupsResponse, GetInstanceGroupData, GetInstanceGroupResponse, CreateInstanceGroupData, CreateInstanceGroupResponse, UpdateInstanceGroupData, UpdateInstanceGroupResponse, DeleteInstanceGroupData, DeleteInstanceGroupResponse, AddUserToInstanceGroupData, AddUserToInstanceGroupResponse, RemoveUserFromInstanceGroupData, RemoveUserFromInstanceGroupResponse, ExportInstanceGroupsResponse, OverwriteInstanceGroupsData, OverwriteInstanceGroupsResponse, ListGroupsData, ListGroupsResponse, ListGroupNamesData, ListGroupNamesResponse, CreateGroupData, CreateGroupResponse, UpdateGroupData, UpdateGroupResponse, DeleteGroupData, DeleteGroupResponse, GetGroupData, GetGroupResponse, AddUserToGroupData, AddUserToGroupResponse, RemoveUserToGroupData, RemoveUserToGroupResponse, ListFoldersData, ListFoldersResponse, ListFolderNamesData, ListFolderNamesResponse, CreateFolderData, CreateFolderResponse, UpdateFolderData, UpdateFolderResponse, DeleteFolderData, DeleteFolderResponse, GetFolderData, GetFolderResponse, GetFolderUsageData, GetFolderUsageResponse, AddOwnerToFolderData, AddOwnerToFolderResponse, RemoveOwnerToFolderData, RemoveOwnerToFolderResponse, ListWorkersData, ListWorkersResponse, ExistsWorkerWithTagData, ExistsWorkerWithTagResponse, GetQueueMetricsResponse, GetCountsOfJobsWaitingPerTagResponse, ListWorkerGroupsResponse, GetConfigData, GetConfigResponse, UpdateConfigData, UpdateConfigResponse, DeleteConfigData, DeleteConfigResponse, ListConfigsResponse, ListAutoscalingEventsData, ListAutoscalingEventsResponse, GetGranularAclsData, GetGranularAclsResponse, AddGranularAclsData, AddGranularAclsResponse, RemoveGranularAclsData, RemoveGranularAclsResponse, SetCaptureConfigData, SetCaptureConfigResponse, PingCaptureConfigData, PingCaptureConfigResponse, GetCaptureConfigsData, GetCaptureConfigsResponse, ListCapturesData, ListCapturesResponse, GetCaptureData, GetCaptureResponse, DeleteCaptureData, DeleteCaptureResponse, StarData, StarResponse, UnstarData, UnstarResponse, GetInputHistoryData, GetInputHistoryResponse, GetArgsFromHistoryOrSavedInputData, GetArgsFromHistoryOrSavedInputResponse, ListInputsData, ListInputsResponse, CreateInputData, CreateInputResponse, UpdateInputData, UpdateInputResponse, DeleteInputData, DeleteInputResponse, DuckdbConnectionSettingsData, DuckdbConnectionSettingsResponse, DuckdbConnectionSettingsV2Data, DuckdbConnectionSettingsV2Response, PolarsConnectionSettingsData, PolarsConnectionSettingsResponse, PolarsConnectionSettingsV2Data, PolarsConnectionSettingsV2Response, S3ResourceInfoData, S3ResourceInfoResponse, DatasetStorageTestConnectionData, DatasetStorageTestConnectionResponse, ListStoredFilesData, ListStoredFilesResponse, LoadFileMetadataData, LoadFileMetadataResponse, LoadFilePreviewData, LoadFilePreviewResponse, LoadParquetPreviewData, LoadParquetPreviewResponse, LoadTableRowCountData, LoadTableRowCountResponse, LoadCsvPreviewData, LoadCsvPreviewResponse, DeleteS3FileData, DeleteS3FileResponse, MoveS3FileData, MoveS3FileResponse, FileUploadData, FileUploadResponse, FileDownloadData, FileDownloadResponse, FileDownloadParquetAsCsvData, FileDownloadParquetAsCsvResponse, GetJobMetricsData, GetJobMetricsResponse, SetJobProgressData, SetJobProgressResponse, GetJobProgressData, GetJobProgressResponse, ListLogFilesData, ListLogFilesResponse, GetLogFileData, GetLogFileResponse, ListConcurrencyGroupsResponse, DeleteConcurrencyGroupData, DeleteConcurrencyGroupResponse, GetConcurrencyKeyData, GetConcurrencyKeyResponse, ListExtendedJobsData, ListExtendedJobsResponse, SearchJobsIndexData, SearchJobsIndexResponse, SearchLogsIndexData, SearchLogsIndexResponse, CountSearchLogsIndexData, CountSearchLogsIndexResponse, ClearIndexData, ClearIndexResponse } from './types.gen.ts'; /** * get backend version @@ -6091,6 +6091,160 @@ export const testNatsConnection = (data: TestNatsConnectionData): CancelableProm mediaType: 'application/json' }); }; +/** + * create sqs trigger + * @param data The data for the request. + * @param data.workspace + * @param data.requestBody new sqs trigger + * @returns string sqs trigger created + * @throws ApiError + */ +export const createSqsTrigger = (data: CreateSqsTriggerData): CancelablePromise => { return __request(OpenAPI, { + method: 'POST', + url: '/w/{workspace}/sqs_triggers/create', + path: { + workspace: data.workspace + }, + body: data.requestBody, + mediaType: 'application/json' +}); }; + +/** + * update sqs trigger + * @param data The data for the request. + * @param data.workspace + * @param data.path + * @param data.requestBody updated trigger + * @returns string sqs trigger updated + * @throws ApiError + */ +export const updateSqsTrigger = (data: UpdateSqsTriggerData): CancelablePromise => { return __request(OpenAPI, { + method: 'POST', + url: '/w/{workspace}/sqs_triggers/update/{path}', + path: { + workspace: data.workspace, + path: data.path + }, + body: data.requestBody, + mediaType: 'application/json' +}); }; + +/** + * delete sqs trigger + * @param data The data for the request. + * @param data.workspace + * @param data.path + * @returns string sqs trigger deleted + * @throws ApiError + */ +export const deleteSqsTrigger = (data: DeleteSqsTriggerData): CancelablePromise => { return __request(OpenAPI, { + method: 'DELETE', + url: '/w/{workspace}/sqs_triggers/delete/{path}', + path: { + workspace: data.workspace, + path: data.path + } +}); }; + +/** + * get sqs trigger + * @param data The data for the request. + * @param data.workspace + * @param data.path + * @returns SqsTrigger sqs trigger deleted + * @throws ApiError + */ +export const getSqsTrigger = (data: GetSqsTriggerData): CancelablePromise => { return __request(OpenAPI, { + method: 'GET', + url: '/w/{workspace}/sqs_triggers/get/{path}', + path: { + workspace: data.workspace, + path: data.path + } +}); }; + +/** + * list sqs triggers + * @param data The data for the request. + * @param data.workspace + * @param data.page which page to return (start at 1, default 1) + * @param data.perPage number of items to return for a given page (default 30, max 100) + * @param data.path filter by path + * @param data.isFlow + * @param data.pathStart + * @returns SqsTrigger sqs trigger list + * @throws ApiError + */ +export const listSqsTriggers = (data: ListSqsTriggersData): CancelablePromise => { return __request(OpenAPI, { + method: 'GET', + url: '/w/{workspace}/sqs_triggers/list', + path: { + workspace: data.workspace + }, + query: { + page: data.page, + per_page: data.perPage, + path: data.path, + is_flow: data.isFlow, + path_start: data.pathStart + } +}); }; + +/** + * does sqs trigger exists + * @param data The data for the request. + * @param data.workspace + * @param data.path + * @returns boolean sqs trigger exists + * @throws ApiError + */ +export const existsSqsTrigger = (data: ExistsSqsTriggerData): CancelablePromise => { return __request(OpenAPI, { + method: 'GET', + url: '/w/{workspace}/sqs_triggers/exists/{path}', + path: { + workspace: data.workspace, + path: data.path + } +}); }; + +/** + * set enabled sqs trigger + * @param data The data for the request. + * @param data.workspace + * @param data.path + * @param data.requestBody updated sqs trigger enable + * @returns string sqs trigger enabled set + * @throws ApiError + */ +export const setSqsTriggerEnabled = (data: SetSqsTriggerEnabledData): CancelablePromise => { return __request(OpenAPI, { + method: 'POST', + url: '/w/{workspace}/sqs_triggers/setenabled/{path}', + path: { + workspace: data.workspace, + path: data.path + }, + body: data.requestBody, + mediaType: 'application/json' +}); }; + +/** + * test sqs connection + * @param data The data for the request. + * @param data.workspace + * @param data.requestBody test sqs connection + * @returns string successfuly connected to sqs + * @throws ApiError + */ +export const testSqsConnection = (data: TestSqsConnectionData): CancelablePromise => { return __request(OpenAPI, { + method: 'POST', + url: '/w/{workspace}/sqs_triggers/test', + path: { + workspace: data.workspace + }, + body: data.requestBody, + mediaType: 'application/json' +}); }; + /** * check if postgres configuration is set to logical * @param data The data for the request. @@ -6435,6 +6589,24 @@ export const setPostgresTriggerEnabled = (data: SetPostgresTriggerEnabledData): mediaType: 'application/json' }); }; +/** + * test postgres connection + * @param data The data for the request. + * @param data.workspace + * @param data.requestBody test postgres connection + * @returns string successfuly connected to postgres + * @throws ApiError + */ +export const testPostgresConnection = (data: TestPostgresConnectionData): CancelablePromise => { return __request(OpenAPI, { + method: 'POST', + url: '/w/{workspace}/postgres_triggers/test', + path: { + workspace: data.workspace + }, + body: data.requestBody, + mediaType: 'application/json' +}); }; + /** * list instance groups * @returns InstanceGroup instance group list diff --git a/cli/gen/types.gen.ts b/cli/gen/types.gen.ts index 075aa848ee..8fdbed7a57 100644 --- a/cli/gen/types.gen.ts +++ b/cli/gen/types.gen.ts @@ -555,6 +555,8 @@ export type EditSchedule = { }; export type TriggerExtraProperty = { + path: string; + script_path: string; email: string; extra_perms: { [key: string]: (boolean); @@ -562,18 +564,16 @@ export type TriggerExtraProperty = { workspace_id: string; edited_by: string; edited_at: string; + is_flow: boolean; }; export type HttpTrigger = TriggerExtraProperty & { - path: string; - script_path: string; route_path: string; static_asset_config?: { s3: string; storage?: string; filename?: string; }; - is_flow: boolean; http_method: 'get' | 'post' | 'put' | 'delete' | 'patch'; is_async: boolean; requires_auth: boolean; @@ -626,13 +626,11 @@ export type TriggersCount = { postgres_count?: number; kafka_count?: number; nats_count?: number; + sqs_count?: number; }; export type WebsocketTrigger = TriggerExtraProperty & { - path: string; - script_path: string; url: string; - is_flow: boolean; server_id?: string; last_server_ping?: string; error?: string; @@ -685,6 +683,36 @@ export type WebsocketTriggerInitialMessage = { }; }; +export type SqsTrigger = TriggerExtraProperty & { + queue_url: string; + aws_resource_path: string; + message_attributes?: Array<(string)>; + server_id?: string; + last_server_ping?: string; + error?: string; + enabled: boolean; +}; + +export type NewSqsTrigger = { + queue_url: string; + aws_resource_path: string; + message_attributes?: Array<(string)>; + path: string; + script_path: string; + is_flow: boolean; + enabled?: boolean; +}; + +export type EditSqsTrigger = { + queue_url: string; + aws_resource_path: string; + message_attributes?: Array<(string)>; + path: string; + script_path: string; + is_flow: boolean; + enabled: boolean; +}; + export type Slot = { name?: string; }; @@ -719,9 +747,6 @@ export type TemplateScript = { }; export type PostgresTrigger = TriggerExtraProperty & { - path: string; - script_path: string; - is_flow: boolean; enabled: boolean; postgres_resource_path: string; publication_name: string; @@ -753,20 +778,10 @@ export type EditPostgresTrigger = { publication?: PublicationData; }; -export type KafkaTrigger = { - path: string; - edited_by: string; - edited_at: string; - script_path: string; +export type KafkaTrigger = TriggerExtraProperty & { kafka_resource_path: string; group_id: string; topics: Array<(string)>; - is_flow: boolean; - extra_perms: { - [key: string]: (boolean); - }; - email: string; - workspace_id: string; server_id?: string; last_server_ping?: string; error?: string; @@ -792,22 +807,12 @@ export type EditKafkaTrigger = { is_flow: boolean; }; -export type NatsTrigger = { - path: string; - edited_by: string; - edited_at: string; - script_path: string; +export type NatsTrigger = TriggerExtraProperty & { nats_resource_path: string; use_jetstream: boolean; stream_name?: string; consumer_name?: string; subjects: Array<(string)>; - is_flow: boolean; - extra_perms: { - [key: string]: (boolean); - }; - email: string; - workspace_id: string; server_id?: string; last_server_ping?: string; error?: string; @@ -1282,7 +1287,7 @@ export type CriticalAlert = { workspace_id?: (string) | null; }; -export type CaptureTriggerKind = 'webhook' | 'http' | 'websocket' | 'kafka' | 'email' | 'nats'; +export type CaptureTriggerKind = 'webhook' | 'http' | 'websocket' | 'kafka' | 'email' | 'nats' | 'postgres' | 'sqs'; export type Capture = { trigger_kind: CaptureTriggerKind; @@ -2751,6 +2756,7 @@ export type GetUsedTriggersResponse = ({ kafka_used: boolean; nats_used: boolean; postgres_used: boolean; + sqs_used: boolean; }); export type ListUsersData = { @@ -5850,6 +5856,95 @@ export type TestNatsConnectionData = { export type TestNatsConnectionResponse = (string); +export type CreateSqsTriggerData = { + /** + * new sqs trigger + */ + requestBody: NewSqsTrigger; + workspace: string; +}; + +export type CreateSqsTriggerResponse = (string); + +export type UpdateSqsTriggerData = { + path: string; + /** + * updated trigger + */ + requestBody: EditSqsTrigger; + workspace: string; +}; + +export type UpdateSqsTriggerResponse = (string); + +export type DeleteSqsTriggerData = { + path: string; + workspace: string; +}; + +export type DeleteSqsTriggerResponse = (string); + +export type GetSqsTriggerData = { + path: string; + workspace: string; +}; + +export type GetSqsTriggerResponse = (SqsTrigger); + +export type ListSqsTriggersData = { + isFlow?: boolean; + /** + * which page to return (start at 1, default 1) + */ + page?: number; + /** + * filter by path + */ + path?: string; + pathStart?: string; + /** + * number of items to return for a given page (default 30, max 100) + */ + perPage?: number; + workspace: string; +}; + +export type ListSqsTriggersResponse = (Array); + +export type ExistsSqsTriggerData = { + path: string; + workspace: string; +}; + +export type ExistsSqsTriggerResponse = (boolean); + +export type SetSqsTriggerEnabledData = { + path: string; + /** + * updated sqs trigger enable + */ + requestBody: { + enabled: boolean; + }; + workspace: string; +}; + +export type SetSqsTriggerEnabledResponse = (string); + +export type TestSqsConnectionData = { + /** + * test sqs connection + */ + requestBody: { + connection: { + [key: string]: unknown; + }; + }; + workspace: string; +}; + +export type TestSqsConnectionResponse = (string); + export type IsValidPostgresConfigurationData = { path: string; workspace: string; @@ -6025,6 +6120,18 @@ export type SetPostgresTriggerEnabledData = { export type SetPostgresTriggerEnabledResponse = (string); +export type TestPostgresConnectionData = { + /** + * test postgres connection + */ + requestBody: { + database: string; + }; + workspace: string; +}; + +export type TestPostgresConnectionResponse = (string); + export type ListInstanceGroupsResponse = (Array); export type GetInstanceGroupData = { @@ -6372,7 +6479,7 @@ export type ListAutoscalingEventsData = { export type ListAutoscalingEventsResponse = (Array); export type GetGranularAclsData = { - kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger'; + kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger' | 'sqs_trigger'; path: string; workspace: string; }; @@ -6382,7 +6489,7 @@ export type GetGranularAclsResponse = ({ }); export type AddGranularAclsData = { - kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger'; + kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger' | 'sqs_trigger'; path: string; /** * acl to add @@ -6397,7 +6504,7 @@ export type AddGranularAclsData = { export type AddGranularAclsResponse = (string); export type RemoveGranularAclsData = { - kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger'; + kind: 'script' | 'group_' | 'resource' | 'schedule' | 'variable' | 'flow' | 'folder' | 'app' | 'raw_app' | 'http_trigger' | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' | 'postgres_trigger' | 'sqs_trigger'; path: string; /** * acl to add diff --git a/cli/sync.ts b/cli/sync.ts index e350b94fef..151244709b 100644 --- a/cli/sync.ts +++ b/cli/sync.ts @@ -640,7 +640,8 @@ export async function elementsToMap( path.endsWith(".websocket_trigger" + ext) || path.endsWith(".kafka_trigger" + ext) || path.endsWith(".nats_trigger" + ext) || - path.endsWith(".postgres_trigger" + ext)) + path.endsWith(".postgres_trigger" + ext) || + path.endsWith(".sqs_trigger" + ext)) ) continue; if (!skips.includeUsers && path.endsWith(".user" + ext)) continue; @@ -885,7 +886,8 @@ function getOrderFromPath(p: string) { typ == "websocket_trigger" || typ == "kafka_trigger" || typ == "nats_trigger" || - typ == "postgres_trigger" + typ == "postgres_trigger" || + typ == "sqs_trigger" ) { return 8; } else if (typ == "variable") { @@ -1719,6 +1721,12 @@ export async function push(opts: GlobalOptions & SyncOptions) { path: removeSuffix(target, ".postgres_trigger.json"), }); break; + case "sqs_trigger": + await wmill.deleteSqsTrigger({ + workspace: workspaceId, + path: removeSuffix(target, ".sqs_trigger.json"), + }); + break; case "variable": await wmill.deleteVariable({ workspace: workspaceId, diff --git a/cli/trigger.ts b/cli/trigger.ts index 9f0b9d887b..39a95890b9 100644 --- a/cli/trigger.ts +++ b/cli/trigger.ts @@ -4,6 +4,7 @@ import { KafkaTrigger, NatsTrigger, PostgresTrigger, + SqsTrigger, WebsocketTrigger, } from "./gen/types.gen.ts"; import { colors, Command, log, SEP, Table } from "./deps.ts"; @@ -23,6 +24,7 @@ type Trigger = { kafka: KafkaTrigger; nats: NatsTrigger; postgres: PostgresTrigger; + sqs: SqsTrigger; }; type TriggerFile = Omit< @@ -54,6 +56,7 @@ async function getTrigger( kafka: wmill.getKafkaTrigger, nats: wmill.getNatsTrigger, postgres: wmill.getPostgresTrigger, + sqs: wmill.getSqsTrigger, }; const triggerFunction = triggerFunctions[triggerType]; @@ -79,6 +82,7 @@ async function updateTrigger( kafka: wmill.updateKafkaTrigger, nats: wmill.updateNatsTrigger, postgres: wmill.updatePostgresTrigger, + sqs: wmill.updateSqsTrigger, }; const triggerFunction = triggerFunctions[triggerType]; await triggerFunction({ workspace, path, requestBody: trigger }); @@ -102,6 +106,7 @@ async function createTrigger( kafka: wmill.createKafkaTrigger, nats: wmill.createNatsTrigger, postgres: wmill.createPostgresTrigger, + sqs: wmill.createSqsTrigger, }; const triggerFunction = triggerFunctions[triggerType]; await triggerFunction({ workspace, path, requestBody: trigger }); @@ -175,6 +180,9 @@ async function list(opts: GlobalOptions) { const postgresTriggers = await wmill.listPostgresTriggers({ workspace: workspace.workspaceId, }); + const sqsTriggers = await wmill.listSqsTriggers({ + workspace: workspace.workspaceId, + }); const triggers = [ ...httpTriggers.map((x) => ({ path: x.path, kind: "http" })), @@ -182,6 +190,7 @@ async function list(opts: GlobalOptions) { ...kafkaTriggers.map((x) => ({ path: x.path, kind: "kafka" })), ...natsTriggers.map((x) => ({ path: x.path, kind: "nats" })), ...postgresTriggers.map((x) => ({ path: x.path, kind: "postgres" })), + ...sqsTriggers.map((x) => ({ path: x.path, kind: "sqs" })), ]; new Table() @@ -195,7 +204,7 @@ async function list(opts: GlobalOptions) { function checkIfValidTrigger(kind: string | undefined): kind is TriggerType { if ( kind && - ["http", "websocket", "kafka", "nats", "postgres"].includes(kind) + ["http", "websocket", "kafka", "nats", "postgres", "sqs"].includes(kind) ) { return true; } else { diff --git a/cli/types.ts b/cli/types.ts index c075ca51d3..18479edbcb 100644 --- a/cli/types.ts +++ b/cli/types.ts @@ -150,6 +150,8 @@ export async function pushObj( await pushTrigger("nats", workspace, p, befObj, newObj); } else if (typeEnding === "postgres_trigger") { await pushTrigger("postgres", workspace, p, befObj, newObj); + } else if (typeEnding === "sqs_trigger") { + await pushTrigger("sqs", workspace, p, befObj, newObj); } else if (typeEnding === "user") { await pushWorkspaceUser(workspace, p, befObj, newObj); } else if (typeEnding === "group") { @@ -197,6 +199,7 @@ export function getTypeStrFromPath( | "kafka_trigger" | "nats_trigger" | "postgres_trigger" + | "sqs_trigger" | "user" | "group" | "settings" @@ -242,6 +245,7 @@ export function getTypeStrFromPath( typeEnding === "kafka_trigger" || typeEnding === "nats_trigger" || typeEnding === "postgres_trigger" || + typeEnding === "sqs_trigger" || typeEnding === "user" || typeEnding === "group" || typeEnding === "settings" || diff --git a/frontend/src/lib/components/Path.svelte b/frontend/src/lib/components/Path.svelte index c66f29c390..8a83a2f872 100644 --- a/frontend/src/lib/components/Path.svelte +++ b/frontend/src/lib/components/Path.svelte @@ -17,7 +17,8 @@ WebsocketTriggerService, KafkaTriggerService, PostgresTriggerService, - NatsTriggerService + NatsTriggerService, + SqsTriggerService } from '$lib/gen' import { superadmin, userStore, workspaceStore } from '$lib/stores' import { createEventDispatcher, getContext } from 'svelte' @@ -43,6 +44,7 @@ | 'kafka_trigger' | 'postgres_trigger' | 'nats_trigger' + | 'sqs_trigger' let meta: Meta | undefined = undefined export let fullNamePlaceholder: string | undefined = undefined export let namePlaceholder = '' @@ -246,6 +248,11 @@ workspace: $workspaceStore!, path: path }) + } else if (kind == 'sqs_trigger') { + return await SqsTriggerService.existsSqsTrigger({ + workspace: $workspaceStore!, + path: path + }) } else { return false } diff --git a/frontend/src/lib/components/ShareModal.svelte b/frontend/src/lib/components/ShareModal.svelte index fe6dcda387..611653f413 100644 --- a/frontend/src/lib/components/ShareModal.svelte +++ b/frontend/src/lib/components/ShareModal.svelte @@ -28,6 +28,7 @@ | 'websocket_trigger' | 'kafka_trigger' | 'nats_trigger' + | 'sqs_trigger' | 'postgres_trigger' let kind: Kind diff --git a/frontend/src/lib/components/details/DetailPageDetailPanel.svelte b/frontend/src/lib/components/details/DetailPageDetailPanel.svelte index 6781e8888a..562b60e08a 100644 --- a/frontend/src/lib/components/details/DetailPageDetailPanel.svelte +++ b/frontend/src/lib/components/details/DetailPageDetailPanel.svelte @@ -15,6 +15,7 @@ | 'postgres' | 'scheduledPoll' | 'kafka' + | 'sqs' | 'nats' = 'webhooks' export let flow_json: any | undefined = undefined export let simplfiedPoll: boolean = false @@ -54,9 +55,10 @@ - + + diff --git a/frontend/src/lib/components/details/DetailPageLayout.svelte b/frontend/src/lib/components/details/DetailPageLayout.svelte index 27c2f46778..808632f83e 100644 --- a/frontend/src/lib/components/details/DetailPageLayout.svelte +++ b/frontend/src/lib/components/details/DetailPageLayout.svelte @@ -30,6 +30,7 @@ | 'scheduledPoll' | 'kafka' | 'nats' + | 'sqs' >('webhooks') const simplifiedPoll = writable(false) @@ -64,9 +65,10 @@ - + + @@ -111,9 +113,10 @@ - + + diff --git a/frontend/src/lib/components/details/DetailPageTriggerPanel.svelte b/frontend/src/lib/components/details/DetailPageTriggerPanel.svelte index 3bf60b99ab..563972556b 100644 --- a/frontend/src/lib/components/details/DetailPageTriggerPanel.svelte +++ b/frontend/src/lib/components/details/DetailPageTriggerPanel.svelte @@ -8,9 +8,7 @@ Webhook, Unplug, PlugZap, - Database - } from 'lucide-svelte' import HighlightTheme from '../HighlightTheme.svelte' @@ -18,6 +16,7 @@ import NatsIcon from '../icons/NatsIcon.svelte' import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte' import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte' + import { AwsIcon } from '../icons' export let triggerSelected: | 'webhooks' @@ -29,13 +28,14 @@ | 'kafka' | 'postgres' | 'nats' + | 'sqs' | 'scheduledPoll' = 'webhooks' export let simplfiedPoll: boolean = false - export let eventStreamType: 'kafka' | 'nats' = 'kafka' + export let eventStreamType: 'kafka' | 'nats' | 'sqs' = 'kafka' $: { - if (triggerSelected === 'kafka' || triggerSelected === 'nats') { + if (triggerSelected === 'kafka' || triggerSelected === 'nats' || triggerSelected === 'sqs') { eventStreamType = triggerSelected } } @@ -76,7 +76,7 @@ Postgres - + Event streams @@ -109,17 +109,20 @@ {:else if triggerSelected === 'postgres'} - {:else if triggerSelected === 'kafka' || triggerSelected === 'nats'} + {:else if triggerSelected === 'kafka' || triggerSelected === 'nats' || triggerSelected === 'sqs'}
+
{#if eventStreamType === 'kafka'} {:else if eventStreamType === 'nats'} + {:else if eventStreamType === 'sqs'} + {/if} {:else if triggerSelected === 'cli'} diff --git a/frontend/src/lib/components/graph/renderers/triggers/TriggersBadge.svelte b/frontend/src/lib/components/graph/renderers/triggers/TriggersBadge.svelte index b3994a707e..2982be5ab6 100644 --- a/frontend/src/lib/components/graph/renderers/triggers/TriggersBadge.svelte +++ b/frontend/src/lib/components/graph/renderers/triggers/TriggersBadge.svelte @@ -12,6 +12,7 @@ import { enterpriseLicense, workspaceStore } from '$lib/stores' import KafkaIcon from '$lib/components/icons/KafkaIcon.svelte' import NatsIcon from '$lib/components/icons/NatsIcon.svelte' + import AwsIcon from '$lib/components/icons/AwsIcon.svelte' const { selectedTrigger, triggersCount } = getContext('TriggerContext') @@ -30,6 +31,7 @@ | 'emails' | 'eventStreams' | 'postgres' + | 'sqs' )[] = showOnlyWithCount ? ['webhooks', 'schedules', 'routes', 'websockets', 'kafka', 'nats', 'emails'] : ['webhooks', 'schedules', 'routes', 'websockets', 'eventStreams', 'emails'] @@ -66,6 +68,7 @@ kafka: { icon: KafkaIcon, countKey: 'kafka_count' }, emails: { icon: Mail, countKey: 'email_count' }, nats: { icon: NatsIcon, countKey: 'nats_count' }, + sqs: { icon: AwsIcon, countKey: 'sqs_count' }, eventStreams: { icon: PlugZap } } @@ -77,7 +80,7 @@ {#each triggersToDisplay as type} {@const { icon, countKey } = triggerTypeConfig[type]} - {#if (!showOnlyWithCount || ((countKey && $triggersCount?.[countKey]) || 0) > 0) && !(type === 'kafka' && !$enterpriseLicense) && !(type === 'nats' && !$enterpriseLicense)} + {#if (!showOnlyWithCount || ((countKey && $triggersCount?.[countKey]) || 0) > 0) && !(type === 'sqs' && !$enterpriseLicense) && !(type === 'kafka' && !$enterpriseLicense) && !(type === 'nats' && !$enterpriseLicense)} {camelCaseToWords(type)} {#if countKey} diff --git a/frontend/src/lib/components/icons/AwsIcon.svelte b/frontend/src/lib/components/icons/AwsIcon.svelte index a3976b4ee3..709193fb9f 100644 --- a/frontend/src/lib/components/icons/AwsIcon.svelte +++ b/frontend/src/lib/components/icons/AwsIcon.svelte @@ -1,10 +1,29 @@ - - - - + + + + diff --git a/frontend/src/lib/components/sidebar/OperatorMenu.svelte b/frontend/src/lib/components/sidebar/OperatorMenu.svelte index ce7001e0c6..afd88041fc 100644 --- a/frontend/src/lib/components/sidebar/OperatorMenu.svelte +++ b/frontend/src/lib/components/sidebar/OperatorMenu.svelte @@ -83,6 +83,11 @@ id: 'triggers', href: `${base}/nats_triggers` }, + { + label: 'SQS triggers', + id: 'triggers', + href: `${base}/sqs_triggers` + }, { label: 'Audit logs', id: 'audit_logs', diff --git a/frontend/src/lib/components/sidebar/SidebarContent.svelte b/frontend/src/lib/components/sidebar/SidebarContent.svelte index 56d1f5f2b6..56e8febc77 100644 --- a/frontend/src/lib/components/sidebar/SidebarContent.svelte +++ b/frontend/src/lib/components/sidebar/SidebarContent.svelte @@ -53,6 +53,7 @@ import SideBarNotification from './SideBarNotification.svelte' import KafkaIcon from '../icons/KafkaIcon.svelte' import NatsIcon from '../icons/NatsIcon.svelte' + import AwsIcon from '../icons/AwsIcon.svelte' export let numUnacknowledgedCriticalAlerts = 0 @@ -121,6 +122,13 @@ icon: NatsIcon, disabled: $userStore?.operator || !$enterpriseLicense, kind: 'nats' + }, + { + label: 'SQS' + ($enterpriseLicense ? '' : ' (EE)'), + href: '/sqs_triggers', + icon: AwsIcon, + disabled: $userStore?.operator || !$enterpriseLicense, + kind: 'sqs' } ] diff --git a/frontend/src/lib/components/triggers.ts b/frontend/src/lib/components/triggers.ts index ac4a905da5..eec8edbd4a 100644 --- a/frontend/src/lib/components/triggers.ts +++ b/frontend/src/lib/components/triggers.ts @@ -51,6 +51,7 @@ export type TriggerKind = | 'kafka' | 'nats' | 'postgres' + | 'sqs' export function captureTriggerKindToTriggerKind(kind: CaptureTriggerKind): TriggerKind { switch (kind) { case 'webhook': @@ -65,6 +66,8 @@ export function captureTriggerKindToTriggerKind(kind: CaptureTriggerKind): Trigg return 'kafka' case 'nats': return 'nats' + case 'sqs': + return 'sqs' case 'postgres': return 'postgres' default: diff --git a/frontend/src/lib/components/triggers/CaptureButton.svelte b/frontend/src/lib/components/triggers/CaptureButton.svelte index b90070d2c1..4dd00caa25 100644 --- a/frontend/src/lib/components/triggers/CaptureButton.svelte +++ b/frontend/src/lib/components/triggers/CaptureButton.svelte @@ -9,6 +9,7 @@ import { captureTriggerKindToTriggerKind } from '../triggers' import CaptureIcon from './CaptureIcon.svelte' import NatsIcon from '../icons/NatsIcon.svelte' + import AwsIcon from '../icons/AwsIcon.svelte' export let small = false @@ -83,6 +84,15 @@
+ +

SQS

+
+ + + {/if} + + {#if drawerLoading} +
+ +

Loading...

+
+ {:else} +
+ + {#if edit} + Changes can take up to 30 seconds to take effect. + {:else} + New postgres triggers can take up to 30 seconds to start listening. + {/if} + +
+
+
+ +
+ +
+

+ Pick a script or flow to be triggered +

+
+ + {#if emptyString(script_path)} + + {/if} +
+
+ + +
+ {/if} + + diff --git a/frontend/src/lib/components/triggers/sqs/SqsTriggerPanel.svelte b/frontend/src/lib/components/triggers/sqs/SqsTriggerPanel.svelte new file mode 100644 index 0000000000..e981d7dedf --- /dev/null +++ b/frontend/src/lib/components/triggers/sqs/SqsTriggerPanel.svelte @@ -0,0 +1,135 @@ + + + { + loadTriggers() + }} + bind:this={sqsTriggerEditor} +/> + +{#if !$enterpriseLicense} + + SQS triggers are an enterprise only feature. + +{:else if isCloudHosted()} + + SQS triggers are disabled in the multi-tenant cloud. + +{:else} +
+ + SQS triggers allow your scripts/flows to process messages from Amazon Simple Queue Service + (SQS) in real time. Each trigger listens to an SQS queue and executes a script or a flow when + new messages arrive. + + + {#if !newItem && sqsTriggers && sqsTriggers.length > 0} +
+
+
+ {#each sqsTriggers as sqsTriggers (sqsTriggers.path)} +
+
{sqsTriggers.path}
+
+ {sqsTriggers.queue_url} +
+
+ +
+
+ {/each} +
+
+
+ {/if} + + { + sqsTriggerEditor?.openNew(isFlow, path, e.detail.config) + }} + on:addPreprocessor + on:updateSchema + on:testWithArgs + cloudDisabled={false} + triggerType="sqs" + {isFlow} + {path} + {isEditor} + {canHavePreprocessor} + {hasPreprocessor} + {newItem} + {openForm} + bind:showCapture={dontCloseOnLoad} + /> +
+{/if} diff --git a/frontend/src/lib/components/triggers/websocket/WebsocketEditorConfigSection.svelte b/frontend/src/lib/components/triggers/websocket/WebsocketEditorConfigSection.svelte index 649b7bcff1..4faa1a17ad 100644 --- a/frontend/src/lib/components/triggers/websocket/WebsocketEditorConfigSection.svelte +++ b/frontend/src/lib/components/triggers/websocket/WebsocketEditorConfigSection.svelte @@ -158,27 +158,29 @@ {:else}
+
+ +
+ +
+
+
- -
- -
-
+ +
+ +
+
+ +
+ +
+
+ import { SqsTriggerService, type SqsTrigger } from '$lib/gen' + import { + canWrite, + displayDate, + getLocalSetting, + sendUserToast, + storeLocalSetting + } from '$lib/utils' + import { base } from '$app/paths' + import CenteredPage from '$lib/components/CenteredPage.svelte' + import { Alert, Button, Skeleton } from '$lib/components/common' + import Dropdown from '$lib/components/DropdownV2.svelte' + import PageHeader from '$lib/components/PageHeader.svelte' + import SharedBadge from '$lib/components/SharedBadge.svelte' + import ShareModal from '$lib/components/ShareModal.svelte' + import Toggle from '$lib/components/Toggle.svelte' + import { userStore, workspaceStore } from '$lib/stores' + import { Code, Eye, Pen, Plus, Share, Trash, Circle, Database } from 'lucide-svelte' + import { goto } from '$lib/navigation' + import SearchItems from '$lib/components/SearchItems.svelte' + import NoItemFound from '$lib/components/home/NoItemFound.svelte' + import RowIcon from '$lib/components/common/table/RowIcon.svelte' + import ListFilters from '$lib/components/home/ListFilters.svelte' + import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte' + import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte' + import { setQuery } from '$lib/navigation' + import { onDestroy, onMount } from 'svelte' + import Popover from '$lib/components/Popover.svelte' + import { isCloudHosted } from '$lib/cloud' + import SqsTriggerEditor from '$lib/components/triggers/sqs/SqsTriggerEditor.svelte' + + type TriggerD = SqsTrigger & { canWrite: boolean } + + let triggers: TriggerD[] = [] + let shareModal: ShareModal + let loading = true + + async function loadTriggers(): Promise { + triggers = (await SqsTriggerService.listSqsTriggers({ workspace: $workspaceStore! })).map( + (x) => { + return { canWrite: canWrite(x.path, x.extra_perms!, $userStore), ...x } + } + ) + loading = false + } + + let interval = setInterval(async () => { + try { + const newTriggers = await SqsTriggerService.listSqsTriggers({ + workspace: $workspaceStore! + }) + for (let i = 0; i < triggers.length; i++) { + const newTrigger = newTriggers.find((x) => x.path === triggers[i].path) + if (newTrigger) { + triggers[i] = { + ...triggers[i], + error: newTrigger.error, + last_server_ping: newTrigger.last_server_ping, + enabled: newTrigger.enabled, + server_id: newTrigger.server_id + } + } + } + } catch (err) { + console.error(err) + } + }, 5000) + + onDestroy(() => { + clearInterval(interval) + }) + + async function setTriggerEnabled(path: string, enabled: boolean): Promise { + try { + await SqsTriggerService.setSqsTriggerEnabled({ + path, + workspace: $workspaceStore!, + requestBody: { enabled } + }) + } catch (err) { + sendUserToast( + `Cannot ` + (enabled ? 'enable' : 'disable') + ` sqs trigger: ${err.body}`, + true + ) + } finally { + loadTriggers() + } + } + + $: { + if ($workspaceStore && $userStore) { + loadTriggers() + } + } + let sqsTriggerEditor: SqsTriggerEditor + + let filteredItems: (TriggerD & { marked?: any })[] | undefined = [] + let items: typeof filteredItems | undefined = [] + let preFilteredItems: typeof filteredItems | undefined = [] + let filter = '' + let ownerFilter: string | undefined = undefined + let nbDisplayed = 15 + + const TRIGGER_PATH_KIND_FILTER_SETTING = 'filter_path_of' + const FILTER_USER_FOLDER_SETTING_NAME = 'user_and_folders_only' + let selectedFilterKind = + (getLocalSetting(TRIGGER_PATH_KIND_FILTER_SETTING) as 'trigger' | 'script_flow') ?? 'trigger' + let filterUserFolders = getLocalSetting(FILTER_USER_FOLDER_SETTING_NAME) == 'true' + + $: storeLocalSetting(TRIGGER_PATH_KIND_FILTER_SETTING, selectedFilterKind) + $: storeLocalSetting(FILTER_USER_FOLDER_SETTING_NAME, filterUserFolders ? 'true' : undefined) + + function filterItemsPathsBaseOnUserFilters( + item: TriggerD, + selectedFilterKind: 'trigger' | 'script_flow', + filterUserFolders: boolean + ) { + if ($workspaceStore == 'admins') return true + if (filterUserFolders) { + if (selectedFilterKind === 'trigger') { + return ( + !item.path.startsWith('u/') || item.path.startsWith('u/' + $userStore?.username + '/') + ) + } else { + return ( + !item.script_path.startsWith('u/') || + item.script_path.startsWith('u/' + $userStore?.username + '/') + ) + } + } else { + return true + } + } + + $: preFilteredItems = + ownerFilter != undefined + ? selectedFilterKind === 'trigger' + ? triggers?.filter( + (x) => + x.path.startsWith(ownerFilter + '/') && + filterItemsPathsBaseOnUserFilters(x, selectedFilterKind, filterUserFolders) + ) + : triggers?.filter( + (x) => + x.script_path.startsWith(ownerFilter + '/') && + filterItemsPathsBaseOnUserFilters(x, selectedFilterKind, filterUserFolders) + ) + : triggers?.filter((x) => + filterItemsPathsBaseOnUserFilters(x, selectedFilterKind, filterUserFolders) + ) + + $: if ($workspaceStore) { + ownerFilter = undefined + } + + $: owners = + selectedFilterKind === 'trigger' + ? Array.from( + new Set(filteredItems?.map((x) => x.path.split('/').slice(0, 2).join('/')) ?? []) + ).sort() + : Array.from( + new Set(filteredItems?.map((x) => x.script_path.split('/').slice(0, 2).join('/')) ?? []) + ).sort() + + $: items = filter !== '' ? filteredItems : preFilteredItems + + function updateQueryFilters(selectedFilterKind, filterUserFolders) { + setQuery( + new URL(window.location.href), + TRIGGER_PATH_KIND_FILTER_SETTING, + selectedFilterKind + ).then(() => { + setQuery( + new URL(window.location.href), + FILTER_USER_FOLDER_SETTING_NAME, + String(filterUserFolders) + ) + }) + } + + function loadQueryFilters() { + let url = new URL(window.location.href) + let queryFilterKind = url.searchParams.get(TRIGGER_PATH_KIND_FILTER_SETTING) + let queryFilterUserFolders = url.searchParams.get(FILTER_USER_FOLDER_SETTING_NAME) + if (queryFilterKind) { + selectedFilterKind = queryFilterKind as 'trigger' | 'script_flow' + } + if (queryFilterUserFolders) { + filterUserFolders = queryFilterUserFolders == 'true' + } + } + + onMount(() => { + loadQueryFilters() + }) + + $: updateQueryFilters(selectedFilterKind, filterUserFolders) + + + + + (x.summary ?? '') + ' ' + x.path + ' (' + x.script_path + ')'} +/> + + + + + + + {#if isCloudHosted()} + + SQS triggers are disabled in the multi-tenant cloud. + +
+ {/if} +
+
+ +
+
Filter by path of
+ + + + +
+ + +
+ {#if $userStore?.is_super_admin && $userStore.username.includes('@')} + + {:else if $userStore?.is_admin || $userStore?.is_super_admin} + + {/if} +
+
+ {#if loading} + {#each new Array(6) as _} + + {/each} + {:else if !triggers?.length} +
No sqs triggers
+ {:else if items?.length} +
+ {#each items.slice(0, nbDisplayed) as { path, edited_by, error, edited_at, script_path, is_flow, extra_perms, canWrite, enabled, server_id } (path)} + {@const href = `${is_flow ? '/flows/get' : '/scripts/get'}/${script_path}`} + {@const ping = new Date()} + {@const pinging = ping && ping.getTime() > new Date().getTime() - 15 * 1000} + +
+
+ + + sqsTriggerEditor?.openEdit(path, is_flow)} + class="min-w-0 grow hover:underline decoration-gray-400" + > +
+ {path} +
+
+
+ runnable: {script_path} +
+
+ + + +
+ {#if (enabled && (!pinging || error)) || (!enabled && error) || (enabled && !server_id)} + + + + + +
+ {#if enabled} + {#if !server_id} + SQS trigger is starting... + {:else} + Could not connect to SQS{error ? ': ' + error : ''} + {/if} + {:else} + Disabled because of an error: {error} + {/if} +
+
+ {:else if enabled} + + + + +
+ Connected to sqs{!server_id ? ' (shutting down...)' : ''}
+
+ {/if} +
+ + { + setTriggerEnabled(path, e.detail) + }} + /> + +
+ + { + goto(href) + } + }, + { + displayName: 'Delete', + type: 'delete', + icon: Trash, + disabled: !canWrite, + action: async () => { + try { + await SqsTriggerService.deleteSqsTrigger({ + workspace: $workspaceStore ?? '', + path + }) + loadTriggers() + } catch (error) { + sendUserToast(error.body, true) + } + } + }, + { + displayName: canWrite ? 'Edit' : 'View', + icon: canWrite ? Pen : Eye, + action: () => { + sqsTriggerEditor?.openEdit(path, is_flow) + } + }, + { + displayName: 'Audit logs', + icon: Eye, + href: `${base}/audit_logs?resource=${path}` + }, + { + displayName: canWrite ? 'Share' : 'See Permissions', + icon: Share, + action: () => { + shareModal.openDrawer(path, 'websocket_trigger') + } + } + ]} + /> +
+
+
+
edited by {edited_by}
the {displayDate(edited_at)}
+
+ {/each} +
+ {:else} + + {/if} +
+ {#if items && items?.length > 15 && nbDisplayed < items.length} + {nbDisplayed} items out of {items.length} + + {/if} + + + { + loadTriggers() + }} +/>