From 48cf3d4c61a604a3bb182e5b7c80fb6caa1adb1c Mon Sep 17 00:00:00 2001 From: Elizabeth Worstell Date: Mon, 25 Nov 2024 10:02:50 -0500 Subject: [PATCH] feat: add sqlc-gen-ftl WASM plugin next step will be hooking this up in the release --- .github/workflows/ci.yml | 14 + .gitignore | 5 +- Justfile | 25 +- backend/protos/buf.gen.yaml | 4 + bin/.rust-src-1.83.0.pkg | 1 + bin/.rustup-1.25.2.pkg | 1 + bin/.rustup-init-1.25.1.pkg | 1 + bin/cargo | 1 + bin/cargo-clippy | 1 + bin/cargo-fmt | 1 + bin/cargo-miri | 1 + bin/clippy-driver | 1 + bin/rls | 1 + bin/rust-analyzer | 1 + bin/rust-gdb | 1 + bin/rust-gdbgui | 1 + bin/rust-lldb | 1 + bin/rust-src | 1 + bin/rustc | 1 + bin/rustdoc | 1 + bin/rustfmt | 1 + bin/rustup | 1 + bin/rustup-init | 1 + internal/sqlc-gen-ftl/Cargo.lock | 1707 +++++++++++++++++ internal/sqlc-gen-ftl/Cargo.toml | 42 + internal/sqlc-gen-ftl/build.rs | 10 + internal/sqlc-gen-ftl/dist/sqlc-gen-ftl.wasm | Bin 0 -> 168600 bytes internal/sqlc-gen-ftl/proto/codegen.proto | 132 ++ internal/sqlc-gen-ftl/src/main.rs | 24 + internal/sqlc-gen-ftl/src/plugin/mod.rs | 187 ++ internal/sqlc-gen-ftl/src/protos/mod.rs | 4 + internal/sqlc-gen-ftl/src/protos/plugin.rs | 191 ++ .../src/protos/xyz.block.ftl.console.v1.rs | 174 ++ .../src/protos/xyz.block.ftl.deployment.v1.rs | 71 + .../src/protos/xyz.block.ftl.language.v1.rs | 411 ++++ .../src/protos/xyz.block.ftl.lease.v1.rs | 13 + .../xyz.block.ftl.provisioner.v1beta1.rs | 105 + .../src/protos/xyz.block.ftl.publish.v1.rs | 18 + .../src/protos/xyz.block.ftl.schema.v1.rs | 803 ++++++++ .../src/protos/xyz.block.ftl.timeline.v1.rs | 534 ++++++ .../src/protos/xyz.block.ftl.v1.console.rs | 656 +++++++ .../src/protos/xyz.block.ftl.v1.language.rs | 396 ++++ .../src/protos/xyz.block.ftl.v1.rs | 571 ++++++ .../src/protos/xyz.block.ftl.v1.schema.rs | 580 ++++++ .../xyz.block.ftl.v1beta1.provisioner.rs | 189 ++ .../sqlc-gen-ftl/test/sqlc_gen_ftl_test.rs | 279 +++ .../sqlc-gen-ftl/test/testdata/queries.sql | 5 + .../sqlc-gen-ftl/test/testdata/schema.sql | 5 + scripts/autofmt | 2 + 49 files changed, 7173 insertions(+), 3 deletions(-) create mode 120000 bin/.rust-src-1.83.0.pkg create mode 120000 bin/.rustup-1.25.2.pkg create mode 120000 bin/.rustup-init-1.25.1.pkg create mode 120000 bin/cargo create mode 120000 bin/cargo-clippy create mode 120000 bin/cargo-fmt create mode 120000 bin/cargo-miri create mode 120000 bin/clippy-driver create mode 120000 bin/rls create mode 120000 bin/rust-analyzer create mode 120000 bin/rust-gdb create mode 120000 bin/rust-gdbgui create mode 120000 bin/rust-lldb create mode 120000 bin/rust-src create mode 120000 bin/rustc create mode 120000 bin/rustdoc create mode 120000 bin/rustfmt create mode 120000 bin/rustup create mode 120000 bin/rustup-init create mode 100644 internal/sqlc-gen-ftl/Cargo.lock create mode 100644 internal/sqlc-gen-ftl/Cargo.toml create mode 100644 internal/sqlc-gen-ftl/build.rs create mode 100755 internal/sqlc-gen-ftl/dist/sqlc-gen-ftl.wasm create mode 100644 internal/sqlc-gen-ftl/proto/codegen.proto create mode 100644 internal/sqlc-gen-ftl/src/main.rs create mode 100644 internal/sqlc-gen-ftl/src/plugin/mod.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/mod.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/plugin.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.console.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.deployment.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.language.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.lease.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.provisioner.v1beta1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.publish.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.schema.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.timeline.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.console.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.language.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.schema.rs create mode 100644 internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1beta1.provisioner.rs create mode 100644 internal/sqlc-gen-ftl/test/sqlc_gen_ftl_test.rs create mode 100644 internal/sqlc-gen-ftl/test/testdata/queries.sql create mode 100644 internal/sqlc-gen-ftl/test/testdata/schema.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71ff9fe512..a64c3582fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,20 @@ jobs: uses: cashapp/activate-hermit@v1.1.3 - name: Test Scripts run: just test-scripts + test-wasm: + name: Test sqlc-gen-ftl + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Init Hermit + uses: cashapp/activate-hermit@v1.1.3 + - name: Build Cache + uses: ./.github/actions/build-cache + - name: Install Rust Toolchain + run: just rust-toolchain-install + - name: Test WASM + run: cd internal/sqlc-gen-ftl && cargo test --features ci --test sqlc_gen_ftl_test -- --nocapture sql: name: SQL runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 2aaadded28..744f059e2b 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,7 @@ charts/**/output/ __pycache__/ *.pyc *.pyo -.venv/ \ No newline at end of file +.venv/ + +# Rust +!internal/sqlc-gen-ftl/dist/ diff --git a/Justfile b/Justfile index 5faae23c5d..0b21fa4ad4 100644 --- a/Justfile +++ b/Justfile @@ -19,6 +19,7 @@ ZIP_DIRS := "go-runtime/compile/build-template " + \ CONSOLE_ROOT := "frontend/console" FRONTEND_OUT := CONSOLE_ROOT + "/dist/index.html" EXTENSION_OUT := "frontend/vscode/dist/extension.js" +SQLC_GEN_FTL_OUT := "internal/sqlc-gen-ftl/dist" PROTOS_IN := "backend/protos" PROTOS_OUT := "backend/protos/xyz/block/ftl/console/v1/console.pb.go " + \ "backend/protos/xyz/block/ftl//v1/ftl.pb.go " + \ @@ -73,6 +74,7 @@ clean: rm -rf python-runtime/ftl/.venv find . -name '*.zip' -exec rm {} \; mvn -f jvm-runtime/ftl-runtime clean + cd internal/sqlc-gen-ftl && cargo clean # Live rebuild the ftl binary whenever source changes. live-rebuild: @@ -83,7 +85,7 @@ dev *args: watchexec -r {{WATCHEXEC_ARGS}} -- "just build-sqlc && ftl dev --plain {{args}}" # Build everything -build-all: build-protos-unconditionally build-backend build-frontend build-backend-tests build-generate build-sqlc build-zips lsp-generate build-jvm build-language-plugins build-go2proto-testdata +build-all: build-protos-unconditionally build-backend build-frontend build-backend-tests build-generate build-sqlc build-zips lsp-generate build-jvm build-language-plugins build-go2proto-testdata build-sqlc-gen-ftl # Run "go generate" on all packages build-generate: @@ -176,6 +178,14 @@ build-frontend: pnpm-install build-extension: pnpm-install @mk {{EXTENSION_OUT}} : frontend/vscode/src frontend/vscode/package.json -- "cd frontend/vscode && rm -f ftl-*.vsix && pnpm run compile" +# Build the sqlc-ftl-gen plugin, used to generate FTL schema from SQL +build-sqlc-gen-ftl: build-protos update-sqlc-plugin-codegen-proto rust-toolchain-install + @mk {{SQLC_GEN_FTL_OUT}} : internal/sqlc-gen-ftl/src -- \ + "cd internal/sqlc-gen-ftl && \ + rustup target add wasm32-wasip1 && \ + cargo build --target wasm32-wasip1 --release && \ + cp target/wasm32-wasip1/release/sqlc-gen-ftl.wasm ../../{{SQLC_GEN_FTL_OUT}}" + # Install development version of VSCode extension install-extension: build-extension @cd frontend/vscode && vsce package && code --install-extension ftl-*.vsix @@ -200,6 +210,17 @@ format-frontend: pnpm-install: @for i in {1..3}; do mk frontend/**/node_modules : frontend/**/package.json -- "pnpm install --frozen-lockfile" && break || sleep 5; done +# Install Rust dependencies based on Cargo.toml +rust-toolchain-install: + @mk internal/sqlc-gen-ftl/target : internal/sqlc-gen-ftl/Cargo.toml -- \ + "cd internal/sqlc-gen-ftl && \ + rustup-init -y --no-modify-path --default-toolchain stable && \ + cargo install protoc-gen-prost && \ + cargo build" + +update-sqlc-plugin-codegen-proto: + curl -L --fail --show-error --silent "https://raw.githubusercontent.com/sqlc-dev/sqlc/main/protos/plugin/codegen.proto" -o "internal/sqlc-gen-ftl/proto/codegen.proto" + # Regenerate protos build-protos: @mk {{SCHEMA_OUT}} : internal/schema -- "@just go2proto" @@ -213,7 +234,7 @@ go2proto: xyz.block.ftl.schema.v1 {{GO_SCHEMA_ROOTS}} && buf format -w && buf lint && bin/gofmt -w internal/schema/go2proto.to.go # Unconditionally rebuild protos -build-protos-unconditionally: go2proto lint-protos pnpm-install +build-protos-unconditionally: go2proto lint-protos pnpm-install rust-toolchain-install cd backend/protos && buf generate # Run integration test(s) diff --git a/backend/protos/buf.gen.yaml b/backend/protos/buf.gen.yaml index dd8e9a8765..585ddab862 100644 --- a/backend/protos/buf.gen.yaml +++ b/backend/protos/buf.gen.yaml @@ -16,3 +16,7 @@ plugins: out: ../../python-runtime/ftl/src/ftl/protos opt: - pyi_out=../../python-runtime/ftl/src/ftl/protos + - plugin: prost + out: ../../internal/sqlc-gen-ftl/src/protos + opt: + - bytes=. diff --git a/bin/.rust-src-1.83.0.pkg b/bin/.rust-src-1.83.0.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.rust-src-1.83.0.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/.rustup-1.25.2.pkg b/bin/.rustup-1.25.2.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.rustup-1.25.2.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/.rustup-init-1.25.1.pkg b/bin/.rustup-init-1.25.1.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.rustup-init-1.25.1.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/cargo b/bin/cargo new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/cargo @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/cargo-clippy b/bin/cargo-clippy new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/cargo-clippy @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/cargo-fmt b/bin/cargo-fmt new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/cargo-fmt @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/cargo-miri b/bin/cargo-miri new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/cargo-miri @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/clippy-driver b/bin/clippy-driver new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/clippy-driver @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rls b/bin/rls new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rls @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rust-analyzer b/bin/rust-analyzer new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rust-analyzer @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rust-gdb b/bin/rust-gdb new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rust-gdb @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rust-gdbgui b/bin/rust-gdbgui new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rust-gdbgui @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rust-lldb b/bin/rust-lldb new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rust-lldb @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rust-src b/bin/rust-src new file mode 120000 index 0000000000..cdb414bf13 --- /dev/null +++ b/bin/rust-src @@ -0,0 +1 @@ +.rust-src-1.83.0.pkg \ No newline at end of file diff --git a/bin/rustc b/bin/rustc new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rustc @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rustdoc b/bin/rustdoc new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rustdoc @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rustfmt b/bin/rustfmt new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rustfmt @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rustup b/bin/rustup new file mode 120000 index 0000000000..5046e66f85 --- /dev/null +++ b/bin/rustup @@ -0,0 +1 @@ +.rustup-1.25.2.pkg \ No newline at end of file diff --git a/bin/rustup-init b/bin/rustup-init new file mode 120000 index 0000000000..1e504a3c63 --- /dev/null +++ b/bin/rustup-init @@ -0,0 +1 @@ +.rustup-init-1.25.1.pkg \ No newline at end of file diff --git a/internal/sqlc-gen-ftl/Cargo.lock b/internal/sqlc-gen-ftl/Cargo.lock new file mode 100644 index 0000000000..242cb725b4 --- /dev/null +++ b/internal/sqlc-gen-ftl/Cargo.lock @@ -0,0 +1,1707 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "cpp_demangle" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba4f80548f22dc9c43911907b5e322c5555544ee85f785115701e6a28c9abe1" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-bitset" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005884e3649c3e5ff2dc79e8a94b138f11569cc08a91244a292714d2a86e9156" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-codegen" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4036255ec33ce9a37495dfbcfc4e1118fd34e693eff9a1e106336b7cd16a9b" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-bitset", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.14.5", + "log", + "regalloc2", + "rustc-hash", + "serde", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7ca74f4b68319da11d39e894437cb6e20ec7c2e11fbbda823c3bf207beedff7" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897e54f433a0269c4187871aa06d452214d5515d228d5bdc22219585e9eef895" + +[[package]] +name = "cranelift-control" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29cb4018f5bf59fb53f515fa9d80e6f8c5ce19f198dc538984ebd23ecf8965ec" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "305399fd781a2953ac78c1396f02ff53144f39c33eb7fc7789cf4e8936d13a96" +dependencies = [ + "cranelift-bitset", + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9230b460a128d53653456137751d27baf567947a3ab8c0c4d6e31fd08036d81e" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b961e24ae3ec9813a24a15ae64bbd2a42e4de4d79a7f3225a412e3b94e78d1c8" + +[[package]] +name = "cranelift-native" +version = "0.114.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5bd76df6c9151188dfa428c863b33da5b34561b67f43c0cf3f24a794f9fa1f" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "fxprof-processed-profile" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" +dependencies = [ + "bitflags", + "debugid", + "fxhash", + "serde", + "serde_json", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", + "serde", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" + +[[package]] +name = "ittapi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" +dependencies = [ + "anyhow", + "ittapi-sys", + "log", +] + +[[package]] +name = "ittapi-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" +dependencies = [ + "cc", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "crc32fast", + "hashbrown 0.15.1", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" +dependencies = [ + "bytes", + "heck", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +dependencies = [ + "prost", +] + +[[package]] +name = "protoc-gen-prost" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77eb17a7657a703f30cb9b7ba4d981e4037b8af2d819ab0077514b0bef537406" +dependencies = [ + "once_cell", + "prost", + "prost-build", + "prost-types", + "regex", +] + +[[package]] +name = "psm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +dependencies = [ + "cc", +] + +[[package]] +name = "pulley-interpreter" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3b8d81cf799e20564931e9867ca32de545188c6ee4c2e0f6e41d32f0c7dc6fb" +dependencies = [ + "cranelift-bitset", + "log", + "sptr", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0" +dependencies = [ + "hashbrown 0.14.5", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + +[[package]] +name = "rustix" +version = "0.38.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "sqlc-gen-ftl" +version = "0.1.0" +dependencies = [ + "bytes", + "hex", + "prost", + "prost-build", + "prost-types", + "protoc-gen-prost", + "serde", + "serde_json", + "sha2", + "tempfile", + "wasm-bindgen", + "wasmtime", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" + +[[package]] +name = "wasm-encoder" +version = "0.219.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54" +dependencies = [ + "leb128", + "wasmparser 0.219.1", +] + +[[package]] +name = "wasm-encoder" +version = "0.220.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf48234b389415b226a4daef6562933d38c7b28a8b8f64c5c4130dad1561ab7" +dependencies = [ + "leb128", + "wasmparser 0.220.0", +] + +[[package]] +name = "wasmparser" +version = "0.219.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5" +dependencies = [ + "ahash", + "bitflags", + "hashbrown 0.14.5", + "indexmap", + "semver", + "serde", +] + +[[package]] +name = "wasmparser" +version = "0.220.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e246c2772ce3ebc83f89a2d4487ac5794cad6c309b2071818a88c7db7c36d87b" +dependencies = [ + "bitflags", + "indexmap", +] + +[[package]] +name = "wasmprinter" +version = "0.219.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228cdc1f30c27816da225d239ce4231f28941147d34713dee8f1fff7cb330e54" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser 0.219.1", +] + +[[package]] +name = "wasmtime" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b79302e3e084713249cc5622e8608e7410afdeeea8c8026d04f491d1fab0b4b" +dependencies = [ + "addr2line", + "anyhow", + "async-trait", + "bitflags", + "bumpalo", + "cc", + "cfg-if", + "encoding_rs", + "fxprof-processed-profile", + "gimli", + "hashbrown 0.14.5", + "indexmap", + "ittapi", + "libc", + "libm", + "log", + "mach2", + "memfd", + "object", + "once_cell", + "paste", + "postcard", + "psm", + "pulley-interpreter", + "rayon", + "rustix", + "semver", + "serde", + "serde_derive", + "serde_json", + "smallvec", + "sptr", + "target-lexicon", + "wasm-encoder 0.219.1", + "wasmparser 0.219.1", + "wasmtime-asm-macros", + "wasmtime-cache", + "wasmtime-component-macro", + "wasmtime-component-util", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-slab", + "wasmtime-versioned-export-macros", + "wasmtime-winch", + "wat", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe53a24e7016a5222875d8ca3ad6024b464465985693c42098cd0bb710002c28" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0677a7e76c24746b68e3657f7cc50c0ff122ee7e97bbda6e710c1b790ebc93cb" +dependencies = [ + "anyhow", + "base64", + "directories-next", + "log", + "postcard", + "rustix", + "serde", + "serde_derive", + "sha2", + "toml", + "windows-sys 0.59.0", + "zstd", +] + +[[package]] +name = "wasmtime-component-macro" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e118acbd2bc09b32ad8606bc7cef793bf5019c1b107772e64dc6c76b5055d40b" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6db4f3ee18c699629eabb9c64e77efe5a93a5137f098db7cab295037ba41c2" + +[[package]] +name = "wasmtime-cranelift" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b87e6c78f562b50aff1afd87ff32a57e241424c846c1c8f3c5fd352d2d62906" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "gimli", + "itertools", + "log", + "object", + "smallvec", + "target-lexicon", + "thiserror", + "wasmparser 0.219.1", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-environ" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c25bfeaa16432d59a0706e2463d315ef4c9ebcfaf5605670b99d46373bdf9f27" +dependencies = [ + "anyhow", + "cpp_demangle", + "cranelift-bitset", + "cranelift-entity", + "gimli", + "indexmap", + "log", + "object", + "postcard", + "rustc-demangle", + "semver", + "serde", + "serde_derive", + "smallvec", + "target-lexicon", + "wasm-encoder 0.219.1", + "wasmparser 0.219.1", + "wasmprinter", + "wasmtime-component-util", +] + +[[package]] +name = "wasmtime-fiber" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759ab0caa3821a6211743fe1eed448ab9df439e3af6c60dea15486c055611806" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2a056056e9ac6916c2b8e4743408560300c1355e078c344211f13210d449b3" +dependencies = [ + "object", + "rustix", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91b218a92866f74f35162f5d03a4e0f62cd0e1cc624285b1014275e5d4575fad" +dependencies = [ + "anyhow", + "cfg-if", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmtime-slab" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5f8acf677ee6b3b8ba400dd9753ea4769e56a95c4b30b045ac6d2d54b2f8ea" + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df09be00c38f49172ca9936998938476e3f2df782673a39ae2ef9fb0838341b6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasmtime-winch" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d6b5297bea14d8387c3974b2b011de628cc9b188f135cec752b74fd368964b" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "object", + "target-lexicon", + "wasmparser 0.219.1", + "wasmtime-cranelift", + "wasmtime-environ", + "winch-codegen", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3963c9c29df91564d8bd181eb00d0dbaeafa1b2a01e15952bb7391166b704e" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wit-parser", +] + +[[package]] +name = "wast" +version = "220.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e708c8de08751fd66e70961a32bae9d71901f14a70871e181cb8461a3bb3165" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder 0.220.0", +] + +[[package]] +name = "wat" +version = "1.220.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de4f1d7d59614ba690541360102b995c4eb1b9ed373701d5102cc1a968b1c5a3" +dependencies = [ + "wast", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winch-codegen" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b42b678c8651ec4900d7600037d235429fc985c31cbc33515885ec0d2a9e158" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser 0.219.1", + "wasmtime-cranelift", + "wasmtime-environ", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-parser" +version = "0.219.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.219.1", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/internal/sqlc-gen-ftl/Cargo.toml b/internal/sqlc-gen-ftl/Cargo.toml new file mode 100644 index 0000000000..cbeb8f4357 --- /dev/null +++ b/internal/sqlc-gen-ftl/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "sqlc-gen-ftl" +version = "0.1.0" +edition = "2021" + +[profile.release] +lto = true +opt-level = 's' +strip = true + +[dependencies] +bytes = { version = "1.6.0", default-features = false, features = ["std"] } +prost = { version = "0.13.3", default-features = false, features = ["std"] } +prost-types = { version = "0.13.3", default-features = false, features = ["std"] } +protoc-gen-prost = { version = "0.4.0" } +serde = { version = "1.0", default-features = false, features = ["derive", "alloc", "std"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc", "std"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "0.2" + +[build-dependencies] +prost-build = "0.13.3" + +[dev-dependencies] +hex = "0.4.3" +sha2 = "0.10.6" +tempfile = "3.6.0" +wasmtime = "27.0.0" + +[[bin]] +name = "sqlc-gen-ftl" +path = "src/main.rs" + +[[test]] +name = "sqlc_gen_ftl_test" +path = "test/sqlc_gen_ftl_test.rs" + +[features] +default = [] +ci = [] + diff --git a/internal/sqlc-gen-ftl/build.rs b/internal/sqlc-gen-ftl/build.rs new file mode 100644 index 0000000000..aac872fbfb --- /dev/null +++ b/internal/sqlc-gen-ftl/build.rs @@ -0,0 +1,10 @@ +fn main() -> Result<(), Box> { + let mut config = prost_build::Config::new(); + config + .out_dir("src/protos") + .compile_protos( + &["proto/codegen.proto"], + &["proto/"] + )?; + Ok(()) +} diff --git a/internal/sqlc-gen-ftl/dist/sqlc-gen-ftl.wasm b/internal/sqlc-gen-ftl/dist/sqlc-gen-ftl.wasm new file mode 100755 index 0000000000000000000000000000000000000000..45693c1bffd87f0fc75e87d93f65357e1cc4ca24 GIT binary patch literal 168600 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 literal 0 HcmV?d00001 diff --git a/internal/sqlc-gen-ftl/proto/codegen.proto b/internal/sqlc-gen-ftl/proto/codegen.proto new file mode 100644 index 0000000000..e6faf19bad --- /dev/null +++ b/internal/sqlc-gen-ftl/proto/codegen.proto @@ -0,0 +1,132 @@ +syntax = "proto3"; + +package plugin; + +service CodegenService { + rpc Generate (GenerateRequest) returns (GenerateResponse); +} + +message File { + string name = 1 [json_name = "name"]; + bytes contents = 2 [json_name = "contents"]; +} + +message Settings { + // Rename message was field 5 + // Overides message was field 6 + // PythonCode message was field 8 + // KotlinCode message was field 9 + // GoCode message was field 10; + // JSONCode message was field 11; + reserved 5, 8, 9, 10, 11; + + string version = 1 [json_name = "version"]; + string engine = 2 [json_name = "engine"]; + repeated string schema = 3 [json_name = "schema"]; + repeated string queries = 4 [json_name = "queries"]; + Codegen codegen = 12 [json_name = "codegen"]; +} + +message Codegen { + message Process { + string cmd = 1; + } + message WASM { + string url = 1; + string sha256 = 2; + } + string out = 1 [json_name = "out"]; + string plugin = 2 [json_name = "plugin"]; + bytes options = 3 [json_name = "options"]; + repeated string env = 4 [json_name = "env"]; + Process process = 5 [json_name = "process"]; + WASM wasm = 6 [json_name = "wasm"]; +} + +message Catalog { + string comment = 1; + string default_schema = 2; + string name = 3; + repeated Schema schemas = 4; +} + +message Schema { + string comment = 1; + string name = 2; + repeated Table tables = 3; + repeated Enum enums = 4; + repeated CompositeType composite_types = 5; +} + +message CompositeType { + string name = 1; + string comment = 2; +} + +message Enum { + string name = 1; + repeated string vals = 2; + string comment = 3; +} + +message Table { + Identifier rel = 1; + repeated Column columns = 2; + string comment = 3; +} + +message Identifier { + string catalog = 1; + string schema = 2; + string name = 3; +} + +message Column { + string name = 1; + bool not_null = 3; + bool is_array = 4; + string comment = 5; + int32 length = 6; + bool is_named_param = 7; + bool is_func_call = 8; + + // XXX: Figure out what PostgreSQL calls `foo.id` + string scope = 9; + Identifier table = 10; + string table_alias = 11; + Identifier type = 12; + bool is_sqlc_slice = 13; + Identifier embed_table = 14; + string original_name = 15; + bool unsigned = 16; + int32 array_dims = 17; +} + +message Query { + string text = 1 [json_name = "text"]; + string name = 2 [json_name = "name"]; + string cmd = 3 [json_name = "cmd"]; + repeated Column columns = 4 [json_name = "columns"]; + repeated Parameter params = 5 [json_name = "parameters"]; + repeated string comments = 6 [json_name = "comments"]; + string filename = 7 [json_name = "filename"]; + Identifier insert_into_table = 8 [json_name = "insert_into_table"]; +} + +message Parameter { + int32 number = 1 [json_name = "number"]; + Column column = 2 [json_name = "column"]; +} + +message GenerateRequest { + Settings settings = 1 [json_name = "settings"]; + Catalog catalog = 2 [json_name = "catalog"]; + repeated Query queries = 3 [json_name = "queries"]; + string sqlc_version = 4 [json_name = "sqlc_version"]; + bytes plugin_options = 5 [json_name = "plugin_options"]; + bytes global_options = 6 [json_name = "global_options"]; +} + +message GenerateResponse { + repeated File files = 1 [json_name = "files"]; +} diff --git a/internal/sqlc-gen-ftl/src/main.rs b/internal/sqlc-gen-ftl/src/main.rs new file mode 100644 index 0000000000..0040d89e71 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/main.rs @@ -0,0 +1,24 @@ +mod protos; +mod plugin; + +use std::io::{Read, Write}; +pub use plugin::Plugin; + +fn main() -> Result<(), Box> { + let mut input_bytes = Vec::new(); + if std::io::stdin().read_to_end(&mut input_bytes).is_err() { + std::process::exit(1); + } + + match Plugin::generate_from_input(&input_bytes) { + Ok(output_bytes) => { + if std::io::stdout().write_all(&output_bytes.as_slice()).is_err() { + std::process::exit(1); + } + Ok(()) + } + Err(_) => { + std::process::exit(1); + } + } +} diff --git a/internal/sqlc-gen-ftl/src/plugin/mod.rs b/internal/sqlc-gen-ftl/src/plugin/mod.rs new file mode 100644 index 0000000000..20dc424e5d --- /dev/null +++ b/internal/sqlc-gen-ftl/src/plugin/mod.rs @@ -0,0 +1,187 @@ +#![allow(dead_code)] + +use crate::protos::pluginpb; +use crate::protos::schemapb; +use crate::protos::schemapb::r#type::Value as TypeValue; +use prost::Message; + +pub struct Plugin; + +impl Plugin { + pub fn generate_from_input(input: &[u8]) -> Result, Box> { + let req = pluginpb::GenerateRequest::decode(input)?; + let resp = Self::handle_generate(req)?; + Ok(resp.encode_to_vec()) + } + + fn handle_generate(req: pluginpb::GenerateRequest) -> Result> { + let module = generate_schema(&req)?; + Ok(pluginpb::GenerateResponse { + files: vec![pluginpb::File { + name: "queries.pb".to_string(), + contents: module.encode_to_vec(), + }], + }) + } +} + +fn generate_schema(request: &pluginpb::GenerateRequest) -> Result> { + let mut decls = Vec::new(); + let module_name = get_module_name(request)?; + + for query in &request.queries { + if !query.params.is_empty() { + decls.push(to_verb_request(query)); + } + + if !query.columns.is_empty() { + decls.push(to_verb_response(query)); + } + + decls.push(to_verb(query, &module_name)); + } + + Ok(schemapb::Module { + name: module_name, + builtin: false, + runtime: None, + comments: Vec::new(), + pos: None, + decls, + }) +} + +fn to_verb(query: &pluginpb::Query, module_name: &str) -> schemapb::Decl { + let request_type = if !query.params.is_empty() { + Some(to_schema_ref(module_name, &format!("{}Request", query.name))) + } else { + None + }; + + let response_type = if query.cmd == ":exec" { + None + } else { + Some(to_schema_ref(module_name, &format!("{}Response", query.name))) + }; + + schemapb::Decl { + value: Some(schemapb::decl::Value::Verb(schemapb::Verb { + name: query.name.clone(), + export: false, + runtime: None, + request: request_type, + response: response_type, + pos: None, + comments: Vec::new(), + metadata: Vec::new(), + })), + } +} + +fn to_verb_request(query: &pluginpb::Query) -> schemapb::Decl { + schemapb::Decl { + value: Some(schemapb::decl::Value::Data(schemapb::Data { + name: format!("{}Request", query.name), + export: false, + type_parameters: Vec::new(), + fields: query.params.iter().map(|param| { + let name = param.column.as_ref() + .map(|col| col.name.clone()) + .unwrap_or_else(|| format!("param{}", param.number)); + let sql_type = param.column.as_ref().and_then(|col| col.r#type.as_ref()); + to_schema_field(name, sql_type) + }).collect(), + pos: None, + comments: Vec::new(), + metadata: Vec::new(), + })), + } +} + +fn to_verb_response(query: &pluginpb::Query) -> schemapb::Decl { + schemapb::Decl { + value: Some(schemapb::decl::Value::Data(schemapb::Data { + name: format!("{}Response", query.name), + export: false, + type_parameters: Vec::new(), + fields: query.columns.iter().map(|col| { + to_schema_field(col.name.clone(), col.r#type.as_ref()) + }).collect(), + pos: None, + comments: Vec::new(), + metadata: Vec::new(), + })), + } +} + +fn to_schema_field(name: String, sql_type: Option<&pluginpb::Identifier>) -> schemapb::Field { + schemapb::Field { + name, + r#type: Some(sql_type.map_or_else( + || schemapb::Type { + value: Some(TypeValue::Any(schemapb::Any { pos: None })), + }, + to_schema_type + )), + pos: None, + comments: Vec::new(), + metadata: Vec::new(), + } +} + +fn to_schema_ref(module_name: &str, name: &str) -> schemapb::Type { + schemapb::Type { + value: Some(schemapb::r#type::Value::Ref(schemapb::Ref { + module: module_name.to_string(), + name: name.to_string(), + pos: None, + type_parameters: vec![], + })) + } +} + +fn to_schema_type(sql_type: &pluginpb::Identifier) -> schemapb::Type { + let value = match sql_type.name.as_str() { + "integer" | "bigint" | "smallint" | "serial" | "bigserial" => + TypeValue::Int(schemapb::Int { pos: None }), + "real" | "float" | "double" | "numeric" | "decimal" => + TypeValue::Float(schemapb::Float { pos: None }), + "text" | "varchar" | "char" | "uuid" => + TypeValue::String(schemapb::String { pos: None }), + "boolean" => + TypeValue::Bool(schemapb::Bool { pos: None }), + "timestamp" | "date" | "time" => + TypeValue::Time(schemapb::Time { pos: None }), + "json" | "jsonb" => + TypeValue::Any(schemapb::Any { pos: None }), + "bytea" | "blob" => + TypeValue::Bytes(schemapb::Bytes { pos: None }), + _ => + TypeValue::Any(schemapb::Any { pos: None }), + }; + + schemapb::Type { + value: Some(value), + } +} + +fn get_module_name(req: &pluginpb::GenerateRequest) -> Result> { + let codegen = req.settings + .as_ref() + .ok_or("Missing settings")? + .codegen + .as_ref() + .ok_or("Missing codegen settings")?; + + let options_str = String::from_utf8(codegen.options.clone()) + .map_err(|e| format!("Invalid UTF-8 in options: {}", e))?; + + let options: serde_json::Value = serde_json::from_str(&options_str) + .map_err(|e| format!("Failed to parse JSON options: {}", e))?; + + options.get("module") + .and_then(|v| v.as_str()) + .ok_or("Missing module name in options") + .map(|s| s.to_string()) + .map_err(|e| e.into()) +} diff --git a/internal/sqlc-gen-ftl/src/protos/mod.rs b/internal/sqlc-gen-ftl/src/protos/mod.rs new file mode 100644 index 0000000000..e1630c4317 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/mod.rs @@ -0,0 +1,4 @@ +#[path = "plugin.rs"] +pub mod pluginpb; +#[path = "xyz.block.ftl.v1.schema.rs"] +pub mod schemapb; diff --git a/internal/sqlc-gen-ftl/src/protos/plugin.rs b/internal/sqlc-gen-ftl/src/protos/plugin.rs new file mode 100644 index 0000000000..a676e257ae --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/plugin.rs @@ -0,0 +1,191 @@ +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct File { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "2")] + pub contents: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Settings { + #[prost(string, tag = "1")] + pub version: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub engine: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "3")] + pub schema: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, repeated, tag = "4")] + pub queries: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "12")] + pub codegen: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Codegen { + #[prost(string, tag = "1")] + pub out: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub plugin: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "3")] + pub options: ::prost::alloc::vec::Vec, + #[prost(string, repeated, tag = "4")] + pub env: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "5")] + pub process: ::core::option::Option, + #[prost(message, optional, tag = "6")] + pub wasm: ::core::option::Option, +} +/// Nested message and enum types in `Codegen`. +pub mod codegen { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Process { + #[prost(string, tag = "1")] + pub cmd: ::prost::alloc::string::String, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Wasm { + #[prost(string, tag = "1")] + pub url: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub sha256: ::prost::alloc::string::String, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Catalog { + #[prost(string, tag = "1")] + pub comment: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub default_schema: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "4")] + pub schemas: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Schema { + #[prost(string, tag = "1")] + pub comment: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "3")] + pub tables: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "4")] + pub enums: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub composite_types: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CompositeType { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub comment: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Enum { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(string, repeated, tag = "2")] + pub vals: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag = "3")] + pub comment: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Table { + #[prost(message, optional, tag = "1")] + pub rel: ::core::option::Option, + #[prost(message, repeated, tag = "2")] + pub columns: ::prost::alloc::vec::Vec, + #[prost(string, tag = "3")] + pub comment: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Identifier { + #[prost(string, tag = "1")] + pub catalog: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub schema: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Column { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(bool, tag = "3")] + pub not_null: bool, + #[prost(bool, tag = "4")] + pub is_array: bool, + #[prost(string, tag = "5")] + pub comment: ::prost::alloc::string::String, + #[prost(int32, tag = "6")] + pub length: i32, + #[prost(bool, tag = "7")] + pub is_named_param: bool, + #[prost(bool, tag = "8")] + pub is_func_call: bool, + /// XXX: Figure out what PostgreSQL calls `foo.id` + #[prost(string, tag = "9")] + pub scope: ::prost::alloc::string::String, + #[prost(message, optional, tag = "10")] + pub table: ::core::option::Option, + #[prost(string, tag = "11")] + pub table_alias: ::prost::alloc::string::String, + #[prost(message, optional, tag = "12")] + pub r#type: ::core::option::Option, + #[prost(bool, tag = "13")] + pub is_sqlc_slice: bool, + #[prost(message, optional, tag = "14")] + pub embed_table: ::core::option::Option, + #[prost(string, tag = "15")] + pub original_name: ::prost::alloc::string::String, + #[prost(bool, tag = "16")] + pub unsigned: bool, + #[prost(int32, tag = "17")] + pub array_dims: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Query { + #[prost(string, tag = "1")] + pub text: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub cmd: ::prost::alloc::string::String, + #[prost(message, repeated, tag = "4")] + pub columns: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag = "5")] + pub params: ::prost::alloc::vec::Vec, + #[prost(string, repeated, tag = "6")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag = "7")] + pub filename: ::prost::alloc::string::String, + #[prost(message, optional, tag = "8")] + pub insert_into_table: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Parameter { + #[prost(int32, tag = "1")] + pub number: i32, + #[prost(message, optional, tag = "2")] + pub column: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateRequest { + #[prost(message, optional, tag = "1")] + pub settings: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub catalog: ::core::option::Option, + #[prost(message, repeated, tag = "3")] + pub queries: ::prost::alloc::vec::Vec, + #[prost(string, tag = "4")] + pub sqlc_version: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "5")] + pub plugin_options: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "6")] + pub global_options: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateResponse { + #[prost(message, repeated, tag = "1")] + pub files: ::prost::alloc::vec::Vec, +} diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.console.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.console.v1.rs new file mode 100644 index 0000000000..22f65a69bf --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.console.v1.rs @@ -0,0 +1,174 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Config { + #[prost(message, optional, tag="1")] + pub config: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Data { + #[prost(message, optional, tag="1")] + pub data: ::core::option::Option, + #[prost(string, tag="2")] + pub schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="3")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Database { + #[prost(message, optional, tag="1")] + pub database: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Enum { + #[prost(message, optional, tag="1")] + pub r#enum: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topic { + #[prost(message, optional, tag="1")] + pub topic: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeAlias { + #[prost(message, optional, tag="1")] + pub typealias: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Secret { + #[prost(message, optional, tag="1")] + pub secret: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Verb { + #[prost(message, optional, tag="1")] + pub verb: ::core::option::Option, + #[prost(string, tag="2")] + pub schema: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub json_request_schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Module { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub language: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub verbs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="6")] + pub data: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="7")] + pub secrets: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="8")] + pub configs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="9")] + pub databases: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="10")] + pub enums: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="11")] + pub topics: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="12")] + pub typealiases: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TopologyGroup { + #[prost(string, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topology { + #[prost(message, repeated, tag="1")] + pub levels: ::prost::alloc::vec::Vec, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetModulesRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetModulesResponse { + #[prost(message, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="2")] + pub topology: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct StreamModulesRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamModulesResponse { + #[prost(message, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="2")] + pub topology: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetConfigRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetConfigResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetSecretRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetSecretResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetSecretRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetSecretResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.deployment.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.deployment.v1.rs new file mode 100644 index 0000000000..3e8224ed36 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.deployment.v1.rs @@ -0,0 +1,71 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentContextRequest { + #[prost(string, tag="1")] + pub deployment: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentContextResponse { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub deployment: ::prost::alloc::string::String, + #[prost(map="string, bytes", tag="3")] + pub configs: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::bytes::Bytes>, + #[prost(map="string, bytes", tag="4")] + pub secrets: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::bytes::Bytes>, + #[prost(message, repeated, tag="5")] + pub databases: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="6")] + pub routes: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `GetDeploymentContextResponse`. +pub mod get_deployment_context_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Dsn { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(enumeration="DbType", tag="2")] + pub r#type: i32, + #[prost(string, tag="3")] + pub dsn: ::prost::alloc::string::String, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Route { + #[prost(string, tag="1")] + pub deployment: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub uri: ::prost::alloc::string::String, + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum DbType { + Unspecified = 0, + Postgres = 1, + Mysql = 2, + } + impl DbType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "DB_TYPE_UNSPECIFIED", + Self::Postgres => "DB_TYPE_POSTGRES", + Self::Mysql => "DB_TYPE_MYSQL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DB_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "DB_TYPE_POSTGRES" => Some(Self::Postgres), + "DB_TYPE_MYSQL" => Some(Self::Mysql), + _ => None, + } + } + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.language.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.language.v1.rs new file mode 100644 index 0000000000..7bdeee1efc --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.language.v1.rs @@ -0,0 +1,411 @@ +// @generated +// This file is @generated by prost-build. +/// ModuleConfig contains the configuration for a module, found in the module's ftl.toml file. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfig { + /// Name of the module + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + /// Absolute path to the module's directory + #[prost(string, tag="2")] + pub dir: ::prost::alloc::string::String, + /// The language of the module + #[prost(string, tag="3")] + pub language: ::prost::alloc::string::String, + /// Absolute path to the directory containing all of this module's build artifacts for deployments + #[prost(string, tag="4")] + pub deploy_dir: ::prost::alloc::string::String, + /// Build is the command to build the module. + #[prost(string, optional, tag="5")] + pub build: ::core::option::Option<::prost::alloc::string::String>, + /// DevModeBuild is the command to build the module in dev mode. + #[prost(string, optional, tag="6")] + pub dev_mode_build: ::core::option::Option<::prost::alloc::string::String>, + /// Build lock path to prevent concurrent builds + #[prost(string, tag="7")] + pub build_lock: ::prost::alloc::string::String, + /// The directory to generate protobuf schema files into. These can be picked up by language specific build tools + #[prost(string, optional, tag="8")] + pub generated_schema_dir: ::core::option::Option<::prost::alloc::string::String>, + /// Patterns to watch for file changes + #[prost(string, repeated, tag="9")] + pub watch: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// LanguageConfig contains any metadata specific to a specific language. + /// These are stored in the ftl.toml file under the same key as the language (eg: "go", "java") + #[prost(message, optional, tag="10")] + pub language_config: ::core::option::Option<::prost_types::Struct>, + /// The directory containing the SQL migration files + #[prost(string, tag="11")] + pub sql_migration_dir: ::prost::alloc::string::String, +} +/// ProjectConfig contains the configuration for a project, found in the ftl-project.toml file. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProjectConfig { + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(bool, tag="3")] + pub no_git: bool, + #[prost(bool, tag="4")] + pub hermit: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCreateModuleFlagsRequest { + #[prost(string, tag="1")] + pub language: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCreateModuleFlagsResponse { + #[prost(message, repeated, tag="1")] + pub flags: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `GetCreateModuleFlagsResponse`. +pub mod get_create_module_flags_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Flag { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub help: ::prost::alloc::string::String, + #[prost(string, optional, tag="3")] + pub envar: ::core::option::Option<::prost::alloc::string::String>, + /// short must be a single character + #[prost(string, optional, tag="4")] + pub short: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="5")] + pub placeholder: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="6")] + pub default: ::core::option::Option<::prost::alloc::string::String>, + } +} +/// Request to create a new module. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateModuleRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + /// The root directory for the module, which does not yet exist. + /// The plugin should create the directory. + #[prost(string, tag="2")] + pub dir: ::prost::alloc::string::String, + /// The project configuration + #[prost(message, optional, tag="3")] + pub project_config: ::core::option::Option, + /// Flags contains any values set for those configured in the GetCreateModuleFlags call + #[prost(message, optional, tag="4")] + pub flags: ::core::option::Option<::prost_types::Struct>, +} +/// Response to a create module request. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct CreateModuleResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfigDefaultsRequest { + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, +} +/// ModuleConfigDefaultsResponse provides defaults for ModuleConfig. +/// +/// The result may be cached by FTL, so defaulting logic should not be changing due to normal module changes. +/// For example, it is valid to return defaults based on which build tool is configured within the module directory, +/// as that is not expected to change during normal operation. +/// It is not recommended to read the module's toml file to determine defaults, as when the toml file is updated, +/// the module defaults will not be recalculated. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfigDefaultsResponse { + /// Default relative path to the directory containing all build artifacts for deployments + #[prost(string, tag="1")] + pub deploy_dir: ::prost::alloc::string::String, + /// Default build command + #[prost(string, optional, tag="2")] + pub build: ::core::option::Option<::prost::alloc::string::String>, + /// Dev mode build command, if different from the regular build command + #[prost(string, optional, tag="3")] + pub dev_mode_build: ::core::option::Option<::prost::alloc::string::String>, + /// Build lock path to prevent concurrent builds + #[prost(string, optional, tag="4")] + pub build_lock: ::core::option::Option<::prost::alloc::string::String>, + /// Default relative path to the directory containing generated schema files + #[prost(string, optional, tag="5")] + pub generated_schema_dir: ::core::option::Option<::prost::alloc::string::String>, + /// Default patterns to watch for file changes, relative to the module directory + #[prost(string, repeated, tag="6")] + pub watch: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Default language specific configuration. + /// These defaults are filled in by looking at each root key only. If the key is not present, the default is used. + #[prost(message, optional, tag="7")] + pub language_config: ::core::option::Option<::prost_types::Struct>, + /// Default directory containing the SQL migration files + #[prost(string, tag="8")] + pub sql_migration_dir: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDependenciesRequest { + #[prost(message, optional, tag="1")] + pub module_config: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDependenciesResponse { + #[prost(string, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +/// BuildContext contains contextual information needed to build. +/// +/// Plugins must include the build context's id when a build succeeds or fails. +/// For automatic rebuilds, plugins must use the most recent build context they have received. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildContext { + #[prost(string, tag="1")] + pub id: ::prost::alloc::string::String, + /// The configuration for the module + #[prost(message, optional, tag="2")] + pub module_config: ::core::option::Option, + /// The FTL schema including all dependencies + #[prost(message, optional, tag="3")] + pub schema: ::core::option::Option, + /// The dependencies for the module + #[prost(string, repeated, tag="4")] + pub dependencies: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Build environment provides environment variables to be set for the build command + #[prost(string, repeated, tag="5")] + pub build_env: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildContextUpdatedRequest { + #[prost(message, optional, tag="1")] + pub build_context: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct BuildContextUpdatedResponse { +} +/// Error contains information about an error that occurred during a build. +/// Errors do not always cause a build failure. Use lesser levels to help guide the user. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Error { + #[prost(string, tag="1")] + pub msg: ::prost::alloc::string::String, + #[prost(enumeration="error::ErrorLevel", tag="4")] + pub level: i32, + #[prost(message, optional, tag="5")] + pub pos: ::core::option::Option, + #[prost(enumeration="error::ErrorType", tag="6")] + pub r#type: i32, +} +/// Nested message and enum types in `Error`. +pub mod error { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ErrorLevel { + Unspecified = 0, + Info = 1, + Warn = 2, + Error = 3, + } + impl ErrorLevel { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ERROR_LEVEL_UNSPECIFIED", + Self::Info => "ERROR_LEVEL_INFO", + Self::Warn => "ERROR_LEVEL_WARN", + Self::Error => "ERROR_LEVEL_ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ERROR_LEVEL_UNSPECIFIED" => Some(Self::Unspecified), + "ERROR_LEVEL_INFO" => Some(Self::Info), + "ERROR_LEVEL_WARN" => Some(Self::Warn), + "ERROR_LEVEL_ERROR" => Some(Self::Error), + _ => None, + } + } + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ErrorType { + Unspecified = 0, + Ftl = 1, + /// Compiler errors are errors that are from the compiler. This is useful to avoid duplicate errors + /// being shown to the user when combining errors from multiple sources (eg: an IDE showing compiler + /// errors and FTL errors via LSP). + Compiler = 2, + } + impl ErrorType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ERROR_TYPE_UNSPECIFIED", + Self::Ftl => "ERROR_TYPE_FTL", + Self::Compiler => "ERROR_TYPE_COMPILER", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ERROR_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "ERROR_TYPE_FTL" => Some(Self::Ftl), + "ERROR_TYPE_COMPILER" => Some(Self::Compiler), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Position { + #[prost(string, tag="1")] + pub filename: ::prost::alloc::string::String, + #[prost(int64, tag="2")] + pub line: i64, + #[prost(int64, tag="3")] + pub start_column: i64, + #[prost(int64, tag="4")] + pub end_column: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ErrorList { + #[prost(message, repeated, tag="1")] + pub errors: ::prost::alloc::vec::Vec, +} +/// Request to build a module. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildRequest { + /// The root path for the FTL project + #[prost(string, tag="1")] + pub project_root: ::prost::alloc::string::String, + /// The path to the directory containing all module stubs. Each module stub is in a subdirectory. + #[prost(string, tag="2")] + pub stubs_root: ::prost::alloc::string::String, + /// Indicates whether to watch for file changes and automatically rebuild + #[prost(bool, tag="3")] + pub rebuild_automatically: bool, + #[prost(message, optional, tag="4")] + pub build_context: ::core::option::Option, +} +/// AutoRebuildStarted should be sent when the plugin decides to start rebuilding automatically. +/// +/// It is not required to send this event, though it helps inform the user that their changes are not yet built. +/// FTL may ignore this event if it does not match FTL's current build context and state. +/// If the plugin decides to cancel the build because another build started, no failure or cancellation event needs +/// to be sent. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AutoRebuildStarted { + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, +} +/// BuildSuccess should be sent when a build succeeds. +/// +/// FTL may ignore this event if it does not match FTL's current build context and state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildSuccess { + /// The id of build context used while building. + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, + /// Indicates whether the build was automatically started by the plugin, rather than due to a Build rpc call. + #[prost(bool, tag="2")] + pub is_automatic_rebuild: bool, + /// Module schema for the built module + #[prost(message, optional, tag="3")] + pub module: ::core::option::Option, + /// Paths for files/directories to be deployed + #[prost(string, repeated, tag="4")] + pub deploy: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Name of the docker image to use for the runner + #[prost(string, tag="5")] + pub docker_image: ::prost::alloc::string::String, + /// Errors contains any errors that occurred during the build + /// No errors can have a level of ERROR, instead a BuildFailure should be sent + /// Instead this is useful for INFO and WARN level errors. + #[prost(message, optional, tag="6")] + pub errors: ::core::option::Option, + /// Dev mode endpoint URI. If this is set then rather than trying to deploy the module, FTL will start a runner that + /// connects to this endpoint. + #[prost(string, optional, tag="7")] + pub dev_endpoint: ::core::option::Option<::prost::alloc::string::String>, + /// Dev mode debug port + #[prost(int32, optional, tag="8")] + pub debug_port: ::core::option::Option, + /// Dev mode runner info file, this file is used to allow the runner to communicate provisioner info back to the plugin + #[prost(string, optional, tag="9")] + pub dev_runner_info_file: ::core::option::Option<::prost::alloc::string::String>, +} +/// BuildFailure should be sent when a build fails. +/// +/// FTL may ignore this event if it does not match FTL's current build context and state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildFailure { + /// The id of build context used while building. + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, + /// Indicates whether the build was automatically started by the plugin, rather than due to a Build rpc call. + #[prost(bool, tag="2")] + pub is_automatic_rebuild: bool, + /// Errors contains any errors that occurred during the build + #[prost(message, optional, tag="3")] + pub errors: ::core::option::Option, + /// Indicates the plugin determined that the dependencies in the BuildContext are out of date. + /// If a Build stream is being kept open for automatic rebuilds, FTL will call GetDependencies, followed by + /// BuildContextUpdated. + #[prost(bool, tag="4")] + pub invalidate_dependencies: bool, +} +/// Every type of message that can be streamed from the language plugin for a build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildResponse { + #[prost(oneof="build_response::Event", tags="2, 3, 4")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `BuildResponse`. +pub mod build_response { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag="2")] + AutoRebuildStarted(super::AutoRebuildStarted), + #[prost(message, tag="3")] + BuildSuccess(super::BuildSuccess), + #[prost(message, tag="4")] + BuildFailure(super::BuildFailure), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateStubsRequest { + /// The directory path to generate stubs into + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, + /// The schema of the module to generate stubs for + #[prost(message, optional, tag="2")] + pub module: ::core::option::Option, + /// The module's configuration to generate stubs for + #[prost(message, optional, tag="3")] + pub module_config: ::core::option::Option, + /// Native module configuration is the configuration for a module that uses the plugin's language, if + /// the main moduleConfig provided is of a different language. It is provided as a mechanism to derive + /// language specific information. For example, the language version. + #[prost(message, optional, tag="4")] + pub native_module_config: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct GenerateStubsResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SyncStubReferencesRequest { + #[prost(message, optional, tag="1")] + pub module_config: ::core::option::Option, + /// The path of the directory containing all module stubs. Each module is in a subdirectory + #[prost(string, tag="2")] + pub stubs_root: ::prost::alloc::string::String, + /// The names of all modules that have had stubs generated + #[prost(string, repeated, tag="3")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct SyncStubReferencesResponse { +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.lease.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.lease.v1.rs new file mode 100644 index 0000000000..9000b83491 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.lease.v1.rs @@ -0,0 +1,13 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AcquireLeaseRequest { + #[prost(string, repeated, tag="1")] + pub key: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub ttl: ::core::option::Option<::prost_types::Duration>, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct AcquireLeaseResponse { +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.provisioner.v1beta1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.provisioner.v1beta1.rs new file mode 100644 index 0000000000..772a7f2370 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.provisioner.v1beta1.rs @@ -0,0 +1,105 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProvisionRequest { + #[prost(string, tag="1")] + pub ftl_cluster_id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub desired_module: ::core::option::Option, + #[prost(message, optional, tag="3")] + pub previous_module: ::core::option::Option, + #[prost(string, repeated, tag="4")] + pub kinds: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProvisionResponse { + #[prost(string, tag="1")] + pub provisioning_token: ::prost::alloc::string::String, + #[prost(enumeration="provision_response::ProvisionResponseStatus", tag="2")] + pub status: i32, +} +/// Nested message and enum types in `ProvisionResponse`. +pub mod provision_response { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ProvisionResponseStatus { + Unspecified = 0, + Submitted = 1, + } + impl ProvisionResponseStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "PROVISION_RESPONSE_STATUS_UNSPECIFIED", + Self::Submitted => "PROVISION_RESPONSE_STATUS_SUBMITTED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "PROVISION_RESPONSE_STATUS_UNSPECIFIED" => Some(Self::Unspecified), + "PROVISION_RESPONSE_STATUS_SUBMITTED" => Some(Self::Submitted), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatusRequest { + #[prost(string, tag="1")] + pub provisioning_token: ::prost::alloc::string::String, + /// The outputs of this module are updated if the the status is a success + #[prost(message, optional, tag="2")] + pub desired_module: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProvisioningEvent { + #[prost(oneof="provisioning_event::Value", tags="1, 2, 3, 4")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `ProvisioningEvent`. +pub mod provisioning_event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + ModuleRuntimeEvent(super::super::super::schema::v1::ModuleRuntimeEvent), + #[prost(message, tag="2")] + DatabaseRuntimeEvent(super::super::super::schema::v1::DatabaseRuntimeEvent), + #[prost(message, tag="3")] + TopicRuntimeEvent(super::super::super::schema::v1::TopicRuntimeEvent), + #[prost(message, tag="4")] + VerbRuntimeEvent(super::super::super::schema::v1::VerbRuntimeEvent), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatusResponse { + #[prost(oneof="status_response::Status", tags="1, 2")] + pub status: ::core::option::Option, +} +/// Nested message and enum types in `StatusResponse`. +pub mod status_response { + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct ProvisioningRunning { + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ProvisioningFailed { + #[prost(string, tag="1")] + pub error_message: ::prost::alloc::string::String, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ProvisioningSuccess { + #[prost(message, repeated, tag="1")] + pub events: ::prost::alloc::vec::Vec, + } + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Status { + #[prost(message, tag="1")] + Running(ProvisioningRunning), + #[prost(message, tag="2")] + Success(ProvisioningSuccess), + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.publish.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.publish.v1.rs new file mode 100644 index 0000000000..5ceecca335 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.publish.v1.rs @@ -0,0 +1,18 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PublishEventRequest { + #[prost(message, optional, tag="1")] + pub topic: ::core::option::Option, + #[prost(bytes="bytes", tag="2")] + pub body: ::prost::bytes::Bytes, + #[prost(string, tag="3")] + pub key: ::prost::alloc::string::String, + /// Only verb name is included because this verb will be in the same module as topic + #[prost(string, tag="4")] + pub caller: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct PublishEventResponse { +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.schema.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.schema.v1.rs new file mode 100644 index 0000000000..305665a364 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.schema.v1.rs @@ -0,0 +1,803 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AwsiamAuthDatabaseConnector { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub username: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub endpoint: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub database: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Any { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Array { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub element: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Bool { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Bytes { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Config { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DsnDatabaseConnector { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub dsn: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Data { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub type_parameters: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="6")] + pub fields: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="7")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Database { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="4")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseConnector { + #[prost(oneof="database_connector::Value", tags="2, 1")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `DatabaseConnector`. +pub mod database_connector { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="2")] + AwsiamAuthDatabaseConnector(super::AwsiamAuthDatabaseConnector), + #[prost(message, tag="1")] + DsnDatabaseConnector(super::DsnDatabaseConnector), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntime { + #[prost(message, optional, tag="1")] + pub connections: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntimeConnections { + #[prost(message, optional, tag="1")] + pub read: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub write: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntimeConnectionsEvent { + #[prost(message, optional, tag="1")] + pub connections: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntimeEvent { + #[prost(string, tag="1")] + pub id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub payload: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntimeEventPayload { + #[prost(oneof="database_runtime_event_payload::Value", tags="1")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `DatabaseRuntimeEventPayload`. +pub mod database_runtime_event_payload { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + DatabaseRuntimeConnectionsEvent(super::DatabaseRuntimeConnectionsEvent), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Decl { + #[prost(oneof="decl::Value", tags="6, 1, 3, 4, 7, 9, 5, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Decl`. +pub mod decl { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="6")] + Config(super::Config), + #[prost(message, tag="1")] + Data(super::Data), + #[prost(message, tag="3")] + Database(super::Database), + #[prost(message, tag="4")] + Enum(super::Enum), + #[prost(message, tag="7")] + Secret(super::Secret), + #[prost(message, tag="9")] + Topic(super::Topic), + #[prost(message, tag="5")] + TypeAlias(super::TypeAlias), + #[prost(message, tag="2")] + Verb(super::Verb), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Enum { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="6")] + pub variants: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EnumVariant { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub value: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Field { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="3")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="5")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Float { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathComponent { + #[prost(oneof="ingress_path_component::Value", tags="1, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `IngressPathComponent`. +pub mod ingress_path_component { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + IngressPathLiteral(super::IngressPathLiteral), + #[prost(message, tag="2")] + IngressPathParameter(super::IngressPathParameter), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathLiteral { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub text: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathParameter { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Int { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IntValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(int64, tag="2")] + pub value: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Map { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub key: ::core::option::Option<::prost::alloc::boxed::Box>, + #[prost(message, optional, boxed, tag="3")] + pub value: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + #[prost(oneof="metadata::Value", tags="5, 14, 1, 10, 3, 4, 9, 2, 12, 6, 13, 11, 7, 8")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Metadata`. +pub mod metadata { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="5")] + Alias(super::MetadataAlias), + #[prost(message, tag="14")] + Artefact(super::MetadataArtefact), + #[prost(message, tag="1")] + Calls(super::MetadataCalls), + #[prost(message, tag="10")] + Config(super::MetadataConfig), + #[prost(message, tag="3")] + CronJob(super::MetadataCronJob), + #[prost(message, tag="4")] + Databases(super::MetadataDatabases), + #[prost(message, tag="9")] + Encoding(super::MetadataEncoding), + #[prost(message, tag="2")] + Ingress(super::MetadataIngress), + #[prost(message, tag="12")] + Publisher(super::MetadataPublisher), + #[prost(message, tag="6")] + Retry(super::MetadataRetry), + #[prost(message, tag="13")] + SqlMigration(super::MetadataSqlMigration), + #[prost(message, tag="11")] + Secrets(super::MetadataSecrets), + #[prost(message, tag="7")] + Subscriber(super::MetadataSubscriber), + #[prost(message, tag="8")] + TypeMap(super::MetadataTypeMap), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataAlias { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(enumeration="AliasKind", tag="2")] + pub kind: i32, + #[prost(string, tag="3")] + pub alias: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataArtefact { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub path: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub digest: ::prost::alloc::string::String, + #[prost(bool, tag="4")] + pub executable: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataCalls { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub calls: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataConfig { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub config: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataCronJob { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub cron: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataDatabases { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub calls: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataEncoding { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub r#type: ::prost::alloc::string::String, + #[prost(bool, tag="3")] + pub lenient: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataIngress { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub method: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub path: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataPublisher { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub topics: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataRetry { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(int64, optional, tag="2")] + pub count: ::core::option::Option, + #[prost(string, tag="3")] + pub min_backoff: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub max_backoff: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub catch: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataSqlMigration { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub digest: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataSecrets { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub secrets: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataSubscriber { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub topic: ::core::option::Option, + #[prost(enumeration="FromOffset", tag="3")] + pub from_offset: i32, + #[prost(bool, tag="4")] + pub dead_letter: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataTypeMap { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub runtime: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub native_name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Module { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub builtin: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="6")] + pub metadata: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="5")] + pub decls: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleRuntime { + #[prost(message, optional, tag="1")] + pub base: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub scaling: ::core::option::Option, + #[prost(message, optional, tag="3")] + pub deployment: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleRuntimeBase { + #[prost(message, optional, tag="1")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(string, tag="2")] + pub language: ::prost::alloc::string::String, + #[prost(string, optional, tag="3")] + pub os: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="4")] + pub arch: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="5")] + pub image: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleRuntimeDeployment { + #[prost(string, tag="1")] + pub endpoint: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub deployment_key: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleRuntimeEvent { + #[prost(oneof="module_runtime_event::Value", tags="1, 3, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `ModuleRuntimeEvent`. +pub mod module_runtime_event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + ModuleRuntimeBase(super::ModuleRuntimeBase), + #[prost(message, tag="3")] + ModuleRuntimeDeployment(super::ModuleRuntimeDeployment), + #[prost(message, tag="2")] + ModuleRuntimeScaling(super::ModuleRuntimeScaling), + } +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ModuleRuntimeScaling { + #[prost(int32, tag="1")] + pub min_replicas: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Optional { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub r#type: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Position { + #[prost(string, tag="1")] + pub filename: ::prost::alloc::string::String, + #[prost(int64, tag="2")] + pub line: i64, + #[prost(int64, tag="3")] + pub column: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Ref { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="3")] + pub module: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub type_parameters: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RuntimeEvent { + #[prost(oneof="runtime_event::Value", tags="5, 1, 3, 2, 6, 4")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `RuntimeEvent`. +pub mod runtime_event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="5")] + DatabaseRuntimeEvent(super::DatabaseRuntimeEvent), + #[prost(message, tag="1")] + ModuleRuntimeBase(super::ModuleRuntimeBase), + #[prost(message, tag="3")] + ModuleRuntimeDeployment(super::ModuleRuntimeDeployment), + #[prost(message, tag="2")] + ModuleRuntimeScaling(super::ModuleRuntimeScaling), + #[prost(message, tag="6")] + TopicRuntimeEvent(super::TopicRuntimeEvent), + #[prost(message, tag="4")] + VerbRuntimeEvent(super::VerbRuntimeEvent), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Schema { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub modules: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Secret { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct String { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StringValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub value: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Time { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topic { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub event: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TopicRuntime { + #[prost(string, repeated, tag="1")] + pub kafka_brokers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub topic_id: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TopicRuntimeEvent { + #[prost(string, tag="1")] + pub id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub payload: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Type { + #[prost(oneof="r#type::Value", tags="9, 7, 5, 4, 2, 1, 8, 12, 11, 3, 6, 10")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Type`. +pub mod r#type { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="9")] + Any(super::Any), + #[prost(message, tag="7")] + Array(::prost::alloc::boxed::Box), + #[prost(message, tag="5")] + Bool(super::Bool), + #[prost(message, tag="4")] + Bytes(super::Bytes), + #[prost(message, tag="2")] + Float(super::Float), + #[prost(message, tag="1")] + Int(super::Int), + #[prost(message, tag="8")] + Map(::prost::alloc::boxed::Box), + #[prost(message, tag="12")] + Optional(::prost::alloc::boxed::Box), + #[prost(message, tag="11")] + Ref(super::Ref), + #[prost(message, tag="3")] + String(super::String), + #[prost(message, tag="6")] + Time(super::Time), + #[prost(message, tag="10")] + Unit(super::Unit), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeAlias { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="6")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeParameter { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub value: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Unit { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Value { + #[prost(oneof="value::Value", tags="2, 1, 3")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Value`. +pub mod value { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="2")] + IntValue(super::IntValue), + #[prost(message, tag="1")] + StringValue(super::StringValue), + #[prost(message, tag="3")] + TypeValue(super::TypeValue), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Verb { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub request: ::core::option::Option, + #[prost(message, optional, tag="6")] + pub response: ::core::option::Option, + #[prost(message, repeated, tag="7")] + pub metadata: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VerbRuntime { + #[prost(message, optional, tag="1")] + pub base: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub subscription: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct VerbRuntimeBase { + #[prost(message, optional, tag="1")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="2")] + pub start_time: ::core::option::Option<::prost_types::Timestamp>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VerbRuntimeEvent { + #[prost(string, tag="1")] + pub id: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub payload: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VerbRuntimePayload { + #[prost(oneof="verb_runtime_payload::Value", tags="1, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `VerbRuntimePayload`. +pub mod verb_runtime_payload { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + VerbRuntimeBase(super::VerbRuntimeBase), + #[prost(message, tag="2")] + VerbRuntimeSubscription(super::VerbRuntimeSubscription), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct VerbRuntimeSubscription { + #[prost(string, repeated, tag="1")] + pub kafka_brokers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AliasKind { + Unspecified = 0, + Json = 1, +} +impl AliasKind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ALIAS_KIND_UNSPECIFIED", + Self::Json => "ALIAS_KIND_JSON", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ALIAS_KIND_UNSPECIFIED" => Some(Self::Unspecified), + "ALIAS_KIND_JSON" => Some(Self::Json), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum FromOffset { + Unspecified = 0, + Beginning = 1, + Latest = 2, +} +impl FromOffset { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "FROM_OFFSET_UNSPECIFIED", + Self::Beginning => "FROM_OFFSET_BEGINNING", + Self::Latest => "FROM_OFFSET_LATEST", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "FROM_OFFSET_UNSPECIFIED" => Some(Self::Unspecified), + "FROM_OFFSET_BEGINNING" => Some(Self::Beginning), + "FROM_OFFSET_LATEST" => Some(Self::Latest), + _ => None, + } + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.timeline.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.timeline.v1.rs new file mode 100644 index 0000000000..5042f7da33 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.timeline.v1.rs @@ -0,0 +1,534 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LogEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(int32, tag="4")] + pub log_level: i32, + #[prost(map="string, string", tag="5")] + pub attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(string, tag="6")] + pub message: ::prost::alloc::string::String, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="8")] + pub stack: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CallEvent { + #[prost(string, optional, tag="1")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(message, optional, tag="3")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="11")] + pub source_verb_ref: ::core::option::Option, + #[prost(message, optional, tag="12")] + pub destination_verb_ref: ::core::option::Option, + #[prost(message, optional, tag="6")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="7")] + pub request: ::prost::alloc::string::String, + #[prost(string, tag="8")] + pub response: ::prost::alloc::string::String, + #[prost(string, optional, tag="9")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="10")] + pub stack: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DeploymentCreatedEvent { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub language: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub module_name: ::prost::alloc::string::String, + #[prost(int32, tag="4")] + pub min_replicas: i32, + #[prost(string, optional, tag="5")] + pub replaced: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DeploymentUpdatedEvent { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub min_replicas: i32, + #[prost(int32, tag="3")] + pub prev_min_replicas: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(string, tag="4")] + pub method: ::prost::alloc::string::String, + #[prost(string, tag="5")] + pub path: ::prost::alloc::string::String, + #[prost(int32, tag="7")] + pub status_code: i32, + #[prost(message, optional, tag="8")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="9")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="10")] + pub request: ::prost::alloc::string::String, + #[prost(string, tag="11")] + pub request_header: ::prost::alloc::string::String, + #[prost(string, tag="12")] + pub response: ::prost::alloc::string::String, + #[prost(string, tag="13")] + pub response_header: ::prost::alloc::string::String, + #[prost(string, optional, tag="14")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CronScheduledEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="3")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="4")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(message, optional, tag="5")] + pub scheduled_at: ::core::option::Option<::prost_types::Timestamp>, + #[prost(string, tag="6")] + pub schedule: ::prost::alloc::string::String, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AsyncExecuteEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="4")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="5")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(enumeration="AsyncExecuteEventType", tag="6")] + pub async_event_type: i32, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PubSubPublishEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="4")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="5")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="6")] + pub topic: ::prost::alloc::string::String, + #[prost(string, tag="7")] + pub request: ::prost::alloc::string::String, + #[prost(string, optional, tag="8")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(int32, tag="9")] + pub partition: i32, + #[prost(int64, tag="10")] + pub offset: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PubSubConsumeEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="3")] + pub dest_verb_module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="4")] + pub dest_verb_name: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="5")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="6")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="7")] + pub topic: ::prost::alloc::string::String, + #[prost(string, optional, tag="8")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(int32, tag="9")] + pub partition: i32, + #[prost(int64, tag="10")] + pub offset: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Event { + #[prost(message, optional, tag="1")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + /// Unique ID for event. + #[prost(int64, tag="2")] + pub id: i64, + #[prost(oneof="event::Entry", tags="3, 4, 5, 6, 7, 8, 9, 10, 11")] + pub entry: ::core::option::Option, +} +/// Nested message and enum types in `Event`. +pub mod event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Entry { + #[prost(message, tag="3")] + Log(super::LogEvent), + #[prost(message, tag="4")] + Call(super::CallEvent), + #[prost(message, tag="5")] + DeploymentCreated(super::DeploymentCreatedEvent), + #[prost(message, tag="6")] + DeploymentUpdated(super::DeploymentUpdatedEvent), + #[prost(message, tag="7")] + Ingress(super::IngressEvent), + #[prost(message, tag="8")] + CronScheduled(super::CronScheduledEvent), + #[prost(message, tag="9")] + AsyncExecute(super::AsyncExecuteEvent), + #[prost(message, tag="10")] + PubsubPublish(super::PubSubPublishEvent), + #[prost(message, tag="11")] + PubsubConsume(super::PubSubConsumeEvent), + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum EventType { + Unspecified = 0, + Log = 1, + Call = 2, + DeploymentCreated = 3, + DeploymentUpdated = 4, + Ingress = 5, + CronScheduled = 6, + AsyncExecute = 7, + PubsubPublish = 8, + PubsubConsume = 9, +} +impl EventType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "EVENT_TYPE_UNSPECIFIED", + Self::Log => "EVENT_TYPE_LOG", + Self::Call => "EVENT_TYPE_CALL", + Self::DeploymentCreated => "EVENT_TYPE_DEPLOYMENT_CREATED", + Self::DeploymentUpdated => "EVENT_TYPE_DEPLOYMENT_UPDATED", + Self::Ingress => "EVENT_TYPE_INGRESS", + Self::CronScheduled => "EVENT_TYPE_CRON_SCHEDULED", + Self::AsyncExecute => "EVENT_TYPE_ASYNC_EXECUTE", + Self::PubsubPublish => "EVENT_TYPE_PUBSUB_PUBLISH", + Self::PubsubConsume => "EVENT_TYPE_PUBSUB_CONSUME", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "EVENT_TYPE_LOG" => Some(Self::Log), + "EVENT_TYPE_CALL" => Some(Self::Call), + "EVENT_TYPE_DEPLOYMENT_CREATED" => Some(Self::DeploymentCreated), + "EVENT_TYPE_DEPLOYMENT_UPDATED" => Some(Self::DeploymentUpdated), + "EVENT_TYPE_INGRESS" => Some(Self::Ingress), + "EVENT_TYPE_CRON_SCHEDULED" => Some(Self::CronScheduled), + "EVENT_TYPE_ASYNC_EXECUTE" => Some(Self::AsyncExecute), + "EVENT_TYPE_PUBSUB_PUBLISH" => Some(Self::PubsubPublish), + "EVENT_TYPE_PUBSUB_CONSUME" => Some(Self::PubsubConsume), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AsyncExecuteEventType { + Unspecified = 0, + Cron = 1, + Pubsub = 2, +} +impl AsyncExecuteEventType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ASYNC_EXECUTE_EVENT_TYPE_UNSPECIFIED", + Self::Cron => "ASYNC_EXECUTE_EVENT_TYPE_CRON", + Self::Pubsub => "ASYNC_EXECUTE_EVENT_TYPE_PUBSUB", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ASYNC_EXECUTE_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "ASYNC_EXECUTE_EVENT_TYPE_CRON" => Some(Self::Cron), + "ASYNC_EXECUTE_EVENT_TYPE_PUBSUB" => Some(Self::Pubsub), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum LogLevel { + Unspecified = 0, + Trace = 1, + Debug = 5, + Info = 9, + Warn = 13, + Error = 17, +} +impl LogLevel { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "LOG_LEVEL_UNSPECIFIED", + Self::Trace => "LOG_LEVEL_TRACE", + Self::Debug => "LOG_LEVEL_DEBUG", + Self::Info => "LOG_LEVEL_INFO", + Self::Warn => "LOG_LEVEL_WARN", + Self::Error => "LOG_LEVEL_ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "LOG_LEVEL_UNSPECIFIED" => Some(Self::Unspecified), + "LOG_LEVEL_TRACE" => Some(Self::Trace), + "LOG_LEVEL_DEBUG" => Some(Self::Debug), + "LOG_LEVEL_INFO" => Some(Self::Info), + "LOG_LEVEL_WARN" => Some(Self::Warn), + "LOG_LEVEL_ERROR" => Some(Self::Error), + _ => None, + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetTimelineRequest { + #[prost(message, repeated, tag="1")] + pub filters: ::prost::alloc::vec::Vec, + #[prost(int32, tag="2")] + pub limit: i32, + /// Ordering is done by id which matches publication order. + /// This roughly corresponds to the time of the event, but not strictly. + #[prost(enumeration="get_timeline_request::Order", tag="3")] + pub order: i32, +} +/// Nested message and enum types in `GetTimelineRequest`. +pub mod get_timeline_request { + /// Filters events by log level. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct LogLevelFilter { + #[prost(enumeration="super::LogLevel", tag="1")] + pub log_level: i32, + } + /// Filters events by deployment key. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DeploymentFilter { + #[prost(string, repeated, tag="1")] + pub deployments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + /// Filters events by request key. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct RequestFilter { + #[prost(string, repeated, tag="1")] + pub requests: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + /// Filters events by event type. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct EventTypeFilter { + #[prost(enumeration="super::EventType", repeated, tag="1")] + pub event_types: ::prost::alloc::vec::Vec, + } + /// Filters events by time. + /// + /// Either end of the time range can be omitted to indicate no bound. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct TimeFilter { + #[prost(message, optional, tag="1")] + pub older_than: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="2")] + pub newer_than: ::core::option::Option<::prost_types::Timestamp>, + } + /// Filters events by ID. + /// + /// Either end of the ID range can be omitted to indicate no bound. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct IdFilter { + #[prost(int64, optional, tag="1")] + pub lower_than: ::core::option::Option, + #[prost(int64, optional, tag="2")] + pub higher_than: ::core::option::Option, + } + /// Filters events by call. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct CallFilter { + #[prost(string, tag="1")] + pub dest_module: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub dest_verb: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="3")] + pub source_module: ::core::option::Option<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ModuleFilter { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub verb: ::core::option::Option<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Filter { + /// These map 1:1 with filters in backend/timeline/filters.go + #[prost(oneof="filter::Filter", tags="1, 2, 3, 4, 5, 6, 7, 8")] + pub filter: ::core::option::Option, + } + /// Nested message and enum types in `Filter`. + pub mod filter { + /// These map 1:1 with filters in backend/timeline/filters.go + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Filter { + #[prost(message, tag="1")] + LogLevel(super::LogLevelFilter), + #[prost(message, tag="2")] + Deployments(super::DeploymentFilter), + #[prost(message, tag="3")] + Requests(super::RequestFilter), + #[prost(message, tag="4")] + EventTypes(super::EventTypeFilter), + #[prost(message, tag="5")] + Time(super::TimeFilter), + #[prost(message, tag="6")] + Id(super::IdFilter), + #[prost(message, tag="7")] + Call(super::CallFilter), + #[prost(message, tag="8")] + Module(super::ModuleFilter), + } + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum Order { + Unspecified = 0, + Asc = 1, + Desc = 2, + } + impl Order { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "ORDER_UNSPECIFIED", + Self::Asc => "ORDER_ASC", + Self::Desc => "ORDER_DESC", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ORDER_UNSPECIFIED" => Some(Self::Unspecified), + "ORDER_ASC" => Some(Self::Asc), + "ORDER_DESC" => Some(Self::Desc), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetTimelineResponse { + #[prost(message, repeated, tag="1")] + pub events: ::prost::alloc::vec::Vec, + /// For pagination, this cursor is where we should start our next query + #[prost(int64, optional, tag="2")] + pub cursor: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamTimelineRequest { + #[prost(message, optional, tag="1")] + pub update_interval: ::core::option::Option<::prost_types::Duration>, + #[prost(message, optional, tag="2")] + pub query: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamTimelineResponse { + #[prost(message, repeated, tag="1")] + pub events: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateEventsRequest { + #[prost(message, repeated, tag="1")] + pub entries: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `CreateEventsRequest`. +pub mod create_events_request { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct EventEntry { + #[prost(message, optional, tag="1")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(oneof="event_entry::Entry", tags="2, 3, 4, 5, 6, 7, 8, 9, 10")] + pub entry: ::core::option::Option, + } + /// Nested message and enum types in `EventEntry`. + pub mod event_entry { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Entry { + #[prost(message, tag="2")] + Log(super::super::LogEvent), + #[prost(message, tag="3")] + Call(super::super::CallEvent), + #[prost(message, tag="4")] + DeploymentCreated(super::super::DeploymentCreatedEvent), + #[prost(message, tag="5")] + DeploymentUpdated(super::super::DeploymentUpdatedEvent), + #[prost(message, tag="6")] + Ingress(super::super::IngressEvent), + #[prost(message, tag="7")] + CronScheduled(super::super::CronScheduledEvent), + #[prost(message, tag="8")] + AsyncExecute(super::super::AsyncExecuteEvent), + #[prost(message, tag="9")] + PubsubPublish(super::super::PubSubPublishEvent), + #[prost(message, tag="10")] + PubsubConsume(super::super::PubSubConsumeEvent), + } + } +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct CreateEventsResponse { +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct DeleteOldEventsRequest { + #[prost(enumeration="EventType", tag="1")] + pub event_type: i32, + #[prost(int64, tag="2")] + pub age_seconds: i64, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct DeleteOldEventsResponse { + #[prost(int64, tag="1")] + pub deleted_count: i64, +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.console.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.console.rs new file mode 100644 index 0000000000..20e42d9fa3 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.console.rs @@ -0,0 +1,656 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LogEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(int32, tag="4")] + pub log_level: i32, + #[prost(map="string, string", tag="5")] + pub attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(string, tag="6")] + pub message: ::prost::alloc::string::String, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="8")] + pub stack: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CallEvent { + #[prost(string, optional, tag="1")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(message, optional, tag="3")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="11")] + pub source_verb_ref: ::core::option::Option, + #[prost(message, optional, tag="12")] + pub destination_verb_ref: ::core::option::Option, + #[prost(message, optional, tag="6")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="7")] + pub request: ::prost::alloc::string::String, + #[prost(string, tag="8")] + pub response: ::prost::alloc::string::String, + #[prost(string, optional, tag="9")] + pub error: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="10")] + pub stack: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DeploymentCreatedEvent { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub language: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub module_name: ::prost::alloc::string::String, + #[prost(int32, tag="4")] + pub min_replicas: i32, + #[prost(string, optional, tag="5")] + pub replaced: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DeploymentUpdatedEvent { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub min_replicas: i32, + #[prost(int32, tag="3")] + pub prev_min_replicas: i32, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(string, tag="4")] + pub method: ::prost::alloc::string::String, + #[prost(string, tag="5")] + pub path: ::prost::alloc::string::String, + #[prost(int32, tag="7")] + pub status_code: i32, + #[prost(message, optional, tag="8")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="9")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="10")] + pub request: ::prost::alloc::string::String, + #[prost(string, tag="11")] + pub request_header: ::prost::alloc::string::String, + #[prost(string, tag="12")] + pub response: ::prost::alloc::string::String, + #[prost(string, tag="13")] + pub response_header: ::prost::alloc::string::String, + #[prost(string, optional, tag="14")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CronScheduledEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="3")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="4")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(message, optional, tag="5")] + pub scheduled_at: ::core::option::Option<::prost_types::Timestamp>, + #[prost(string, tag="6")] + pub schedule: ::prost::alloc::string::String, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AsyncExecuteEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="4")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="5")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(enumeration="AsyncExecuteEventType", tag="6")] + pub async_event_type: i32, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PubSubPublishEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub verb_ref: ::core::option::Option, + #[prost(message, optional, tag="4")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="5")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="6")] + pub topic: ::prost::alloc::string::String, + #[prost(string, tag="7")] + pub request: ::prost::alloc::string::String, + #[prost(string, optional, tag="8")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PubSubConsumeEvent { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="3")] + pub dest_verb_module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="4")] + pub dest_verb_name: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="5")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="6")] + pub duration: ::core::option::Option<::prost_types::Duration>, + #[prost(string, tag="7")] + pub topic: ::prost::alloc::string::String, + #[prost(string, optional, tag="8")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Config { + #[prost(message, optional, tag="1")] + pub config: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Data { + #[prost(message, optional, tag="1")] + pub data: ::core::option::Option, + #[prost(string, tag="2")] + pub schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="3")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Database { + #[prost(message, optional, tag="1")] + pub database: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Enum { + #[prost(message, optional, tag="1")] + pub r#enum: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topic { + #[prost(message, optional, tag="1")] + pub topic: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeAlias { + #[prost(message, optional, tag="1")] + pub typealias: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Secret { + #[prost(message, optional, tag="1")] + pub secret: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Subscription { + #[prost(message, optional, tag="1")] + pub subscription: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Verb { + #[prost(message, optional, tag="1")] + pub verb: ::core::option::Option, + #[prost(string, tag="2")] + pub schema: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub json_request_schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub references: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Module { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub language: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub schema: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub verbs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="6")] + pub data: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="7")] + pub secrets: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="8")] + pub configs: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="9")] + pub databases: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="10")] + pub enums: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="11")] + pub topics: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="12")] + pub typealiases: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="13")] + pub subscriptions: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TopologyGroup { + #[prost(string, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topology { + #[prost(message, repeated, tag="1")] + pub levels: ::prost::alloc::vec::Vec, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetModulesRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetModulesResponse { + #[prost(message, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="2")] + pub topology: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct StreamModulesRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamModulesResponse { + #[prost(message, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="2")] + pub topology: ::core::option::Option, +} +/// Query for events. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EventsQuery { + #[prost(message, repeated, tag="1")] + pub filters: ::prost::alloc::vec::Vec, + #[prost(int32, tag="2")] + pub limit: i32, + #[prost(enumeration="events_query::Order", tag="3")] + pub order: i32, +} +/// Nested message and enum types in `EventsQuery`. +pub mod events_query { + /// Limit the number of events returned. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct LimitFilter { + #[prost(int32, tag="1")] + pub limit: i32, + } + /// Filters events by log level. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct LogLevelFilter { + #[prost(enumeration="super::LogLevel", tag="1")] + pub log_level: i32, + } + /// Filters events by deployment key. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DeploymentFilter { + #[prost(string, repeated, tag="1")] + pub deployments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + /// Filters events by request key. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct RequestFilter { + #[prost(string, repeated, tag="1")] + pub requests: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + } + /// Filters events by event type. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct EventTypeFilter { + #[prost(enumeration="super::EventType", repeated, tag="1")] + pub event_types: ::prost::alloc::vec::Vec, + } + /// Filters events by time. + /// + /// Either end of the time range can be omitted to indicate no bound. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct TimeFilter { + #[prost(message, optional, tag="1")] + pub older_than: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="2")] + pub newer_than: ::core::option::Option<::prost_types::Timestamp>, + } + /// Filters events by ID. + /// + /// Either end of the ID range can be omitted to indicate no bound. + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct IdFilter { + #[prost(int64, optional, tag="1")] + pub lower_than: ::core::option::Option, + #[prost(int64, optional, tag="2")] + pub higher_than: ::core::option::Option, + } + /// Filters events by call. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct CallFilter { + #[prost(string, tag="1")] + pub dest_module: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub dest_verb: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="3")] + pub source_module: ::core::option::Option<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ModuleFilter { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub verb: ::core::option::Option<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Filter { + /// These map 1:1 with filters in backend/controller/internal/dal/events.go + #[prost(oneof="filter::Filter", tags="1, 2, 3, 4, 5, 6, 7, 8, 9")] + pub filter: ::core::option::Option, + } + /// Nested message and enum types in `Filter`. + pub mod filter { + /// These map 1:1 with filters in backend/controller/internal/dal/events.go + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Filter { + #[prost(message, tag="1")] + Limit(super::LimitFilter), + #[prost(message, tag="2")] + LogLevel(super::LogLevelFilter), + #[prost(message, tag="3")] + Deployments(super::DeploymentFilter), + #[prost(message, tag="4")] + Requests(super::RequestFilter), + #[prost(message, tag="5")] + EventTypes(super::EventTypeFilter), + #[prost(message, tag="6")] + Time(super::TimeFilter), + #[prost(message, tag="7")] + Id(super::IdFilter), + #[prost(message, tag="8")] + Call(super::CallFilter), + #[prost(message, tag="9")] + Module(super::ModuleFilter), + } + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum Order { + Asc = 0, + Desc = 1, + } + impl Order { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Asc => "ASC", + Self::Desc => "DESC", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ASC" => Some(Self::Asc), + "DESC" => Some(Self::Desc), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamEventsRequest { + #[prost(message, optional, tag="1")] + pub update_interval: ::core::option::Option<::prost_types::Duration>, + #[prost(message, optional, tag="2")] + pub query: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamEventsResponse { + #[prost(message, repeated, tag="1")] + pub events: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Event { + #[prost(message, optional, tag="1")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + /// Unique ID for event. + #[prost(int64, tag="2")] + pub id: i64, + #[prost(oneof="event::Entry", tags="3, 4, 5, 6, 7, 8, 9, 10, 11")] + pub entry: ::core::option::Option, +} +/// Nested message and enum types in `Event`. +pub mod event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Entry { + #[prost(message, tag="3")] + Log(super::LogEvent), + #[prost(message, tag="4")] + Call(super::CallEvent), + #[prost(message, tag="5")] + DeploymentCreated(super::DeploymentCreatedEvent), + #[prost(message, tag="6")] + DeploymentUpdated(super::DeploymentUpdatedEvent), + #[prost(message, tag="7")] + Ingress(super::IngressEvent), + #[prost(message, tag="8")] + CronScheduled(super::CronScheduledEvent), + #[prost(message, tag="9")] + AsyncExecute(super::AsyncExecuteEvent), + #[prost(message, tag="10")] + PubsubPublish(super::PubSubPublishEvent), + #[prost(message, tag="11")] + PubsubConsume(super::PubSubConsumeEvent), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetEventsResponse { + #[prost(message, repeated, tag="1")] + pub events: ::prost::alloc::vec::Vec, + /// For pagination, this cursor is where we should start our next query + #[prost(int64, optional, tag="2")] + pub cursor: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetConfigResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetConfigRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetConfigResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetSecretRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetSecretResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetSecretRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SetSecretResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum EventType { + Unknown = 0, + Log = 1, + Call = 2, + DeploymentCreated = 3, + DeploymentUpdated = 4, + Ingress = 5, + CronScheduled = 6, + AsyncExecute = 7, + PubsubPublish = 8, + PubsubConsume = 9, +} +impl EventType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unknown => "EVENT_TYPE_UNKNOWN", + Self::Log => "EVENT_TYPE_LOG", + Self::Call => "EVENT_TYPE_CALL", + Self::DeploymentCreated => "EVENT_TYPE_DEPLOYMENT_CREATED", + Self::DeploymentUpdated => "EVENT_TYPE_DEPLOYMENT_UPDATED", + Self::Ingress => "EVENT_TYPE_INGRESS", + Self::CronScheduled => "EVENT_TYPE_CRON_SCHEDULED", + Self::AsyncExecute => "EVENT_TYPE_ASYNC_EXECUTE", + Self::PubsubPublish => "EVENT_TYPE_PUBSUB_PUBLISH", + Self::PubsubConsume => "EVENT_TYPE_PUBSUB_CONSUME", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "EVENT_TYPE_UNKNOWN" => Some(Self::Unknown), + "EVENT_TYPE_LOG" => Some(Self::Log), + "EVENT_TYPE_CALL" => Some(Self::Call), + "EVENT_TYPE_DEPLOYMENT_CREATED" => Some(Self::DeploymentCreated), + "EVENT_TYPE_DEPLOYMENT_UPDATED" => Some(Self::DeploymentUpdated), + "EVENT_TYPE_INGRESS" => Some(Self::Ingress), + "EVENT_TYPE_CRON_SCHEDULED" => Some(Self::CronScheduled), + "EVENT_TYPE_ASYNC_EXECUTE" => Some(Self::AsyncExecute), + "EVENT_TYPE_PUBSUB_PUBLISH" => Some(Self::PubsubPublish), + "EVENT_TYPE_PUBSUB_CONSUME" => Some(Self::PubsubConsume), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AsyncExecuteEventType { + Unknown = 0, + Cron = 1, + Pubsub = 2, +} +impl AsyncExecuteEventType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unknown => "ASYNC_EXECUTE_EVENT_TYPE_UNKNOWN", + Self::Cron => "ASYNC_EXECUTE_EVENT_TYPE_CRON", + Self::Pubsub => "ASYNC_EXECUTE_EVENT_TYPE_PUBSUB", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ASYNC_EXECUTE_EVENT_TYPE_UNKNOWN" => Some(Self::Unknown), + "ASYNC_EXECUTE_EVENT_TYPE_CRON" => Some(Self::Cron), + "ASYNC_EXECUTE_EVENT_TYPE_PUBSUB" => Some(Self::Pubsub), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum LogLevel { + Unknown = 0, + Trace = 1, + Debug = 5, + Info = 9, + Warn = 13, + Error = 17, +} +impl LogLevel { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unknown => "LOG_LEVEL_UNKNOWN", + Self::Trace => "LOG_LEVEL_TRACE", + Self::Debug => "LOG_LEVEL_DEBUG", + Self::Info => "LOG_LEVEL_INFO", + Self::Warn => "LOG_LEVEL_WARN", + Self::Error => "LOG_LEVEL_ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "LOG_LEVEL_UNKNOWN" => Some(Self::Unknown), + "LOG_LEVEL_TRACE" => Some(Self::Trace), + "LOG_LEVEL_DEBUG" => Some(Self::Debug), + "LOG_LEVEL_INFO" => Some(Self::Info), + "LOG_LEVEL_WARN" => Some(Self::Warn), + "LOG_LEVEL_ERROR" => Some(Self::Error), + _ => None, + } + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.language.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.language.rs new file mode 100644 index 0000000000..f94f87ff2e --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.language.rs @@ -0,0 +1,396 @@ +// @generated +// This file is @generated by prost-build. +/// ModuleConfig contains the configuration for a module, found in the module's ftl.toml file. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfig { + /// Name of the module + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + /// Absolute path to the module's directory + #[prost(string, tag="2")] + pub dir: ::prost::alloc::string::String, + /// The language of the module + #[prost(string, tag="3")] + pub language: ::prost::alloc::string::String, + /// Absolute path to the directory containing all of this module's build artifacts for deployments + #[prost(string, tag="4")] + pub deploy_dir: ::prost::alloc::string::String, + /// Build is the command to build the module. + #[prost(string, optional, tag="5")] + pub build: ::core::option::Option<::prost::alloc::string::String>, + /// DevModeBuild is the command to build the module in dev mode. + #[prost(string, optional, tag="6")] + pub dev_mode_build: ::core::option::Option<::prost::alloc::string::String>, + /// Build lock path to prevent concurrent builds + #[prost(string, tag="7")] + pub build_lock: ::prost::alloc::string::String, + /// The directory to generate protobuf schema files into. These can be picked up by language specific build tools + #[prost(string, optional, tag="8")] + pub generated_schema_dir: ::core::option::Option<::prost::alloc::string::String>, + /// Patterns to watch for file changes + #[prost(string, repeated, tag="9")] + pub watch: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// LanguageConfig contains any metadata specific to a specific language. + /// These are stored in the ftl.toml file under the same key as the language (eg: "go", "java") + #[prost(message, optional, tag="10")] + pub language_config: ::core::option::Option<::prost_types::Struct>, +} +/// ProjectConfig contains the configuration for a project, found in the ftl-project.toml file. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProjectConfig { + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(bool, tag="3")] + pub no_git: bool, + #[prost(bool, tag="4")] + pub hermit: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCreateModuleFlagsRequest { + #[prost(string, tag="1")] + pub language: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetCreateModuleFlagsResponse { + #[prost(message, repeated, tag="1")] + pub flags: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `GetCreateModuleFlagsResponse`. +pub mod get_create_module_flags_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Flag { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub help: ::prost::alloc::string::String, + #[prost(string, optional, tag="3")] + pub envar: ::core::option::Option<::prost::alloc::string::String>, + /// short must be a single character + #[prost(string, optional, tag="4")] + pub short: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="5")] + pub placeholder: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="6")] + pub default: ::core::option::Option<::prost::alloc::string::String>, + } +} +/// Request to create a new module. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateModuleRequest { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + /// The root directory for the module, which does not yet exist. + /// The plugin should create the directory. + #[prost(string, tag="2")] + pub dir: ::prost::alloc::string::String, + /// The project configuration + #[prost(message, optional, tag="3")] + pub project_config: ::core::option::Option, + /// Flags contains any values set for those configured in the GetCreateModuleFlags call + #[prost(message, optional, tag="4")] + pub flags: ::core::option::Option<::prost_types::Struct>, +} +/// Response to a create module request. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct CreateModuleResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfigDefaultsRequest { + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, +} +/// ModuleConfigDefaultsResponse provides defaults for ModuleConfig. +/// +/// The result may be cached by FTL, so defaulting logic should not be changing due to normal module changes. +/// For example, it is valid to return defaults based on which build tool is configured within the module directory, +/// as that is not expected to change during normal operation. +/// It is not recommended to read the module's toml file to determine defaults, as when the toml file is updated, +/// the module defaults will not be recalculated. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleConfigDefaultsResponse { + /// Default relative path to the directory containing all build artifacts for deployments + #[prost(string, tag="1")] + pub deploy_dir: ::prost::alloc::string::String, + /// Default build command + #[prost(string, optional, tag="2")] + pub build: ::core::option::Option<::prost::alloc::string::String>, + /// Dev mode build command, if different from the regular build command + #[prost(string, optional, tag="3")] + pub dev_mode_build: ::core::option::Option<::prost::alloc::string::String>, + /// Build lock path to prevent concurrent builds + #[prost(string, optional, tag="4")] + pub build_lock: ::core::option::Option<::prost::alloc::string::String>, + /// Default relative path to the directory containing generated schema files + #[prost(string, optional, tag="5")] + pub generated_schema_dir: ::core::option::Option<::prost::alloc::string::String>, + /// Default patterns to watch for file changes, relative to the module directory + #[prost(string, repeated, tag="6")] + pub watch: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// SQLQueryDir is the path to the SQL query directory, relative to the module directory. + #[prost(string, tag="8")] + pub sql_query_dir: ::prost::alloc::string::String, + /// Default language specific configuration. + /// These defaults are filled in by looking at each root key only. If the key is not present, the default is used. + #[prost(message, optional, tag="7")] + pub language_config: ::core::option::Option<::prost_types::Struct>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DependenciesRequest { + #[prost(message, optional, tag="1")] + pub module_config: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DependenciesResponse { + #[prost(string, repeated, tag="1")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +/// BuildContext contains contextual information needed to build. +/// +/// Plugins must include the build context's id when a build succeeds or fails. +/// For automatic rebuilds, plugins must use the most recent build context they have received. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildContext { + #[prost(string, tag="1")] + pub id: ::prost::alloc::string::String, + /// The configuration for the module + #[prost(message, optional, tag="2")] + pub module_config: ::core::option::Option, + /// The FTL schema including all dependencies + #[prost(message, optional, tag="3")] + pub schema: ::core::option::Option, + /// The dependencies for the module + #[prost(string, repeated, tag="4")] + pub dependencies: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Build environment provides environment variables to be set for the build command + #[prost(string, repeated, tag="5")] + pub build_env: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildContextUpdatedRequest { + #[prost(message, optional, tag="1")] + pub build_context: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct BuildContextUpdatedResponse { +} +/// Error contains information about an error that occurred during a build. +/// Errors do not always cause a build failure. Use lesser levels to help guide the user. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Error { + #[prost(string, tag="1")] + pub msg: ::prost::alloc::string::String, + #[prost(enumeration="error::ErrorLevel", tag="4")] + pub level: i32, + #[prost(message, optional, tag="5")] + pub pos: ::core::option::Option, + #[prost(enumeration="error::ErrorType", tag="6")] + pub r#type: i32, +} +/// Nested message and enum types in `Error`. +pub mod error { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ErrorLevel { + Info = 0, + Warn = 1, + Error = 2, + } + impl ErrorLevel { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Info => "INFO", + Self::Warn => "WARN", + Self::Error => "ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "INFO" => Some(Self::Info), + "WARN" => Some(Self::Warn), + "ERROR" => Some(Self::Error), + _ => None, + } + } + } + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ErrorType { + Ftl = 0, + /// Compiler errors are errors that are from the compiler. This is useful to avoid duplicate errors + /// being shown to the user when combining errors from multiple sources (eg: an IDE showing compiler + /// errors and FTL errors via LSP). + Compiler = 1, + } + impl ErrorType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Ftl => "FTL", + Self::Compiler => "COMPILER", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "FTL" => Some(Self::Ftl), + "COMPILER" => Some(Self::Compiler), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Position { + #[prost(string, tag="1")] + pub filename: ::prost::alloc::string::String, + #[prost(int64, tag="2")] + pub line: i64, + #[prost(int64, tag="3")] + pub start_column: i64, + #[prost(int64, tag="4")] + pub end_column: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ErrorList { + #[prost(message, repeated, tag="1")] + pub errors: ::prost::alloc::vec::Vec, +} +/// Request to build a module. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildRequest { + /// The root path for the FTL project + #[prost(string, tag="1")] + pub project_root: ::prost::alloc::string::String, + /// The path to the directory containing all module stubs. Each module stub is in a subdirectory. + #[prost(string, tag="2")] + pub stubs_root: ::prost::alloc::string::String, + /// Indicates whether to watch for file changes and automatically rebuild + #[prost(bool, tag="3")] + pub rebuild_automatically: bool, + #[prost(message, optional, tag="4")] + pub build_context: ::core::option::Option, +} +/// AutoRebuildStarted should be sent when the plugin decides to start rebuilding automatically. +/// +/// It is not required to send this event, though it helps inform the user that their changes are not yet built. +/// FTL may ignore this event if it does not match FTL's current build context and state. +/// If the plugin decides to cancel the build because another build started, no failure or cancellation event needs +/// to be sent. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AutoRebuildStarted { + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, +} +/// BuildSuccess should be sent when a build succeeds. +/// +/// FTL may ignore this event if it does not match FTL's current build context and state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildSuccess { + /// The id of build context used while building. + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, + /// Indicates whether the build was automatically started by the plugin, rather than due to a Build rpc call. + #[prost(bool, tag="2")] + pub is_automatic_rebuild: bool, + /// Module schema for the built module + #[prost(message, optional, tag="3")] + pub module: ::core::option::Option, + /// Paths for files/directories to be deployed + #[prost(string, repeated, tag="4")] + pub deploy: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Name of the docker image to use for the runner + #[prost(string, tag="5")] + pub docker_image: ::prost::alloc::string::String, + /// Errors contains any errors that occurred during the build + /// No errors can have a level of ERROR, instead a BuildFailure should be sent + /// Instead this is useful for INFO and WARN level errors. + #[prost(message, optional, tag="6")] + pub errors: ::core::option::Option, + /// Dev mode endpoint URI. If this is set then rather than trying to deploy the module, FTL will start a runner that + /// connects to this endpoint. + #[prost(string, optional, tag="7")] + pub dev_endpoint: ::core::option::Option<::prost::alloc::string::String>, +} +/// BuildFailure should be sent when a build fails. +/// +/// FTL may ignore this event if it does not match FTL's current build context and state. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildFailure { + /// The id of build context used while building. + #[prost(string, tag="1")] + pub context_id: ::prost::alloc::string::String, + /// Indicates whether the build was automatically started by the plugin, rather than due to a Build rpc call. + #[prost(bool, tag="2")] + pub is_automatic_rebuild: bool, + /// Errors contains any errors that occurred during the build + #[prost(message, optional, tag="3")] + pub errors: ::core::option::Option, + /// Indicates the plugin determined that the dependencies in the BuildContext are out of date. + /// If a Build stream is being kept open for automatic rebuilds, FTL will call GetDependencies, followed by + /// BuildContextUpdated. + #[prost(bool, tag="4")] + pub invalidate_dependencies: bool, +} +/// Every type of message that can be streamed from the language plugin for a build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BuildEvent { + #[prost(oneof="build_event::Event", tags="2, 3, 4")] + pub event: ::core::option::Option, +} +/// Nested message and enum types in `BuildEvent`. +pub mod build_event { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag="2")] + AutoRebuildStarted(super::AutoRebuildStarted), + #[prost(message, tag="3")] + BuildSuccess(super::BuildSuccess), + #[prost(message, tag="4")] + BuildFailure(super::BuildFailure), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GenerateStubsRequest { + /// The directory path to generate stubs into + #[prost(string, tag="1")] + pub dir: ::prost::alloc::string::String, + /// The schema of the module to generate stubs for + #[prost(message, optional, tag="2")] + pub module: ::core::option::Option, + /// The module's configuration to generate stubs for + #[prost(message, optional, tag="3")] + pub module_config: ::core::option::Option, + /// Native module configuration is the configuration for a module that uses the plugin's language, if + /// the main moduleConfig provided is of a different language. It is provided as a mechanism to derive + /// language specific information. For example, the language version. + #[prost(message, optional, tag="4")] + pub native_module_config: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct GenerateStubsResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SyncStubReferencesRequest { + #[prost(message, optional, tag="1")] + pub module_config: ::core::option::Option, + /// The path of the directory containing all module stubs. Each module is in a subdirectory + #[prost(string, tag="2")] + pub stubs_root: ::prost::alloc::string::String, + /// The names of all modules that have had stubs generated + #[prost(string, repeated, tag="3")] + pub modules: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct SyncStubReferencesResponse { +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.rs new file mode 100644 index 0000000000..6b7a88a4c6 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.rs @@ -0,0 +1,571 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct PingRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PingResponse { + /// If present, the service is not ready to accept requests and this is the + /// reason. + #[prost(string, optional, tag="1")] + pub not_ready: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + #[prost(message, repeated, tag="1")] + pub values: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `Metadata`. +pub mod metadata { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Pair { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub value: ::prost::alloc::string::String, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigRef { + #[prost(string, optional, tag="1")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigListRequest { + #[prost(string, optional, tag="1")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bool, optional, tag="2")] + pub include_values: ::core::option::Option, + #[prost(enumeration="ConfigProvider", optional, tag="3")] + pub provider: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigListResponse { + #[prost(message, repeated, tag="1")] + pub configs: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `ConfigListResponse`. +pub mod config_list_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Config { + #[prost(string, tag="1")] + pub ref_path: ::prost::alloc::string::String, + #[prost(bytes="bytes", optional, tag="2")] + pub value: ::core::option::Option<::prost::bytes::Bytes>, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigGetRequest { + #[prost(message, optional, tag="1")] + pub r#ref: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigGetResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigSetRequest { + #[prost(enumeration="ConfigProvider", optional, tag="1")] + pub provider: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub r#ref: ::core::option::Option, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ConfigSetResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ConfigUnsetRequest { + #[prost(enumeration="ConfigProvider", optional, tag="1")] + pub provider: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub r#ref: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ConfigUnsetResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretsListRequest { + #[prost(string, optional, tag="1")] + pub module: ::core::option::Option<::prost::alloc::string::String>, + #[prost(bool, optional, tag="2")] + pub include_values: ::core::option::Option, + #[prost(enumeration="SecretProvider", optional, tag="3")] + pub provider: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretsListResponse { + #[prost(message, repeated, tag="1")] + pub secrets: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `SecretsListResponse`. +pub mod secrets_list_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Secret { + #[prost(string, tag="1")] + pub ref_path: ::prost::alloc::string::String, + #[prost(bytes="bytes", optional, tag="2")] + pub value: ::core::option::Option<::prost::bytes::Bytes>, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretGetRequest { + #[prost(message, optional, tag="1")] + pub r#ref: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretGetResponse { + #[prost(bytes="bytes", tag="1")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretSetRequest { + #[prost(enumeration="SecretProvider", optional, tag="1")] + pub provider: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub r#ref: ::core::option::Option, + #[prost(bytes="bytes", tag="3")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct SecretSetResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SecretUnsetRequest { + #[prost(enumeration="SecretProvider", optional, tag="1")] + pub provider: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub r#ref: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct SecretUnsetResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MapConfigsForModuleRequest { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MapConfigsForModuleResponse { + #[prost(map="string, bytes", tag="1")] + pub values: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::bytes::Bytes>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MapSecretsForModuleRequest { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MapSecretsForModuleResponse { + #[prost(map="string, bytes", tag="1")] + pub values: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::bytes::Bytes>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ConfigProvider { + Unspecified = 0, + /// Write values inline in the configuration file. + Inline = 1, + /// Print configuration as environment variables. + Envar = 2, + /// Use the database as a configuration store. + Db = 3, +} +impl ConfigProvider { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "CONFIG_PROVIDER_UNSPECIFIED", + Self::Inline => "CONFIG_PROVIDER_INLINE", + Self::Envar => "CONFIG_PROVIDER_ENVAR", + Self::Db => "CONFIG_PROVIDER_DB", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "CONFIG_PROVIDER_UNSPECIFIED" => Some(Self::Unspecified), + "CONFIG_PROVIDER_INLINE" => Some(Self::Inline), + "CONFIG_PROVIDER_ENVAR" => Some(Self::Envar), + "CONFIG_PROVIDER_DB" => Some(Self::Db), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SecretProvider { + Unspecified = 0, + /// Write values inline in the configuration file. + Inline = 1, + /// Print configuration as environment variables. + Envar = 2, + /// Write to the system keychain. + Keychain = 3, + /// Store a secret in the 1Password vault. + Op = 4, + /// Store a secret in the AWS Secrets Manager. + Asm = 5, +} +impl SecretProvider { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "SECRET_PROVIDER_UNSPECIFIED", + Self::Inline => "SECRET_PROVIDER_INLINE", + Self::Envar => "SECRET_PROVIDER_ENVAR", + Self::Keychain => "SECRET_PROVIDER_KEYCHAIN", + Self::Op => "SECRET_PROVIDER_OP", + Self::Asm => "SECRET_PROVIDER_ASM", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SECRET_PROVIDER_UNSPECIFIED" => Some(Self::Unspecified), + "SECRET_PROVIDER_INLINE" => Some(Self::Inline), + "SECRET_PROVIDER_ENVAR" => Some(Self::Envar), + "SECRET_PROVIDER_KEYCHAIN" => Some(Self::Keychain), + "SECRET_PROVIDER_OP" => Some(Self::Op), + "SECRET_PROVIDER_ASM" => Some(Self::Asm), + _ => None, + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetArtefactDiffsRequest { + #[prost(string, repeated, tag="1")] + pub client_digests: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetArtefactDiffsResponse { + #[prost(string, repeated, tag="1")] + pub missing_digests: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Artefacts that the client already has, and their path+executable status. + #[prost(message, repeated, tag="2")] + pub client_artefacts: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UploadArtefactRequest { + #[prost(bytes="bytes", tag="1")] + pub content: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UploadArtefactResponse { + #[prost(bytes="bytes", tag="2")] + pub digest: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DeploymentArtefact { + #[prost(string, tag="1")] + pub digest: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub path: ::prost::alloc::string::String, + #[prost(bool, tag="3")] + pub executable: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateDeploymentRequest { + #[prost(message, optional, tag="1")] + pub schema: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub artefacts: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateDeploymentResponse { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + /// Currently active deployment for this module, if any. + #[prost(string, optional, tag="2")] + pub active_deployment_key: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentArtefactsRequest { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(message, repeated, tag="2")] + pub have_artefacts: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentArtefactsResponse { + #[prost(message, optional, tag="1")] + pub artefact: ::core::option::Option, + #[prost(bytes="bytes", tag="2")] + pub chunk: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentRequest { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetDeploymentResponse { + #[prost(message, optional, tag="1")] + pub schema: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub artefacts: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RegisterRunnerRequest { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub endpoint: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub deployment: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub labels: ::core::option::Option<::prost_types::Struct>, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct RegisterRunnerResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateDeployRequest { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(int32, optional, tag="2")] + pub min_replicas: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct UpdateDeployResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ReplaceDeployRequest { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub min_replicas: i32, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ReplaceDeployResponse { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamDeploymentLogsRequest { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + #[prost(string, optional, tag="2")] + pub request_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub time_stamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(int32, tag="4")] + pub log_level: i32, + #[prost(map="string, string", tag="5")] + pub attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + #[prost(string, tag="6")] + pub message: ::prost::alloc::string::String, + #[prost(string, optional, tag="7")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct StreamDeploymentLogsResponse { +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct StatusRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatusResponse { + #[prost(message, repeated, tag="1")] + pub controllers: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="2")] + pub runners: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="3")] + pub deployments: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="5")] + pub routes: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `StatusResponse`. +pub mod status_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Controller { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub endpoint: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub version: ::prost::alloc::string::String, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Runner { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub endpoint: ::prost::alloc::string::String, + #[prost(string, optional, tag="3")] + pub deployment: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="4")] + pub labels: ::core::option::Option<::prost_types::Struct>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Deployment { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub language: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(int32, tag="4")] + pub min_replicas: i32, + #[prost(int32, tag="7")] + pub replicas: i32, + #[prost(message, optional, tag="5")] + pub labels: ::core::option::Option<::prost_types::Struct>, + #[prost(message, optional, tag="6")] + pub schema: ::core::option::Option, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Route { + #[prost(string, tag="1")] + pub module: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub deployment: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub endpoint: ::prost::alloc::string::String, + } +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct ProcessListRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProcessListResponse { + #[prost(message, repeated, tag="1")] + pub processes: ::prost::alloc::vec::Vec, +} +/// Nested message and enum types in `ProcessListResponse`. +pub mod process_list_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ProcessRunner { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub endpoint: ::prost::alloc::string::String, + #[prost(message, optional, tag="3")] + pub labels: ::core::option::Option<::prost_types::Struct>, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Process { + #[prost(string, tag="1")] + pub deployment: ::prost::alloc::string::String, + #[prost(int32, tag="2")] + pub min_replicas: i32, + #[prost(message, optional, tag="3")] + pub labels: ::core::option::Option<::prost_types::Struct>, + #[prost(message, optional, tag="4")] + pub runner: ::core::option::Option, + } +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetSchemaRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetSchemaResponse { + #[prost(message, optional, tag="1")] + pub schema: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct PullSchemaRequest { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PullSchemaResponse { + /// Will not be set for builtin modules. + #[prost(string, optional, tag="1")] + pub deployment_key: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub module_name: ::prost::alloc::string::String, + /// For deletes this will not be present. + #[prost(message, optional, tag="4")] + pub schema: ::core::option::Option, + /// If true there are more schema changes immediately following this one as part of the initial batch. + /// If false this is the last schema change in the initial batch, but others may follow later. + #[prost(bool, tag="3")] + pub more: bool, + #[prost(enumeration="DeploymentChangeType", tag="5")] + pub change_type: i32, + /// If this is true then the module was removed as well as the deployment. This is only set for DEPLOYMENT_REMOVED. + #[prost(bool, tag="6")] + pub module_removed: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct UpdateDeploymentRuntimeRequest { + #[prost(string, tag="1")] + pub deployment: ::prost::alloc::string::String, + #[prost(message, optional, tag="2")] + pub event: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct UpdateDeploymentRuntimeResponse { +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum DeploymentChangeType { + Unspecified = 0, + Added = 1, + Removed = 2, + Changed = 3, +} +impl DeploymentChangeType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "DEPLOYMENT_CHANGE_TYPE_UNSPECIFIED", + Self::Added => "DEPLOYMENT_CHANGE_TYPE_ADDED", + Self::Removed => "DEPLOYMENT_CHANGE_TYPE_REMOVED", + Self::Changed => "DEPLOYMENT_CHANGE_TYPE_CHANGED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "DEPLOYMENT_CHANGE_TYPE_UNSPECIFIED" => Some(Self::Unspecified), + "DEPLOYMENT_CHANGE_TYPE_ADDED" => Some(Self::Added), + "DEPLOYMENT_CHANGE_TYPE_REMOVED" => Some(Self::Removed), + "DEPLOYMENT_CHANGE_TYPE_CHANGED" => Some(Self::Changed), + _ => None, + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CallRequest { + #[prost(message, optional, tag="1")] + pub metadata: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub verb: ::core::option::Option, + #[prost(bytes="bytes", tag="3")] + pub body: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CallResponse { + #[prost(oneof="call_response::Response", tags="1, 2")] + pub response: ::core::option::Option, +} +/// Nested message and enum types in `CallResponse`. +pub mod call_response { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Error { + #[prost(string, tag="1")] + pub message: ::prost::alloc::string::String, + /// TODO: Richer error type. + #[prost(string, optional, tag="2")] + pub stack: ::core::option::Option<::prost::alloc::string::String>, + } + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Response { + #[prost(bytes, tag="1")] + Body(::prost::bytes::Bytes), + #[prost(message, tag="2")] + Error(Error), + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.schema.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.schema.rs new file mode 100644 index 0000000000..4a7cbcde6e --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1.schema.rs @@ -0,0 +1,580 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Any { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Array { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub element: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Bool { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Bytes { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Config { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Data { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub type_parameters: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="6")] + pub fields: ::prost::alloc::vec::Vec, + #[prost(message, repeated, tag="7")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Database { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="4")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRuntime { + #[prost(string, tag="1")] + pub dsn: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Decl { + #[prost(oneof="decl::Value", tags="6, 1, 3, 4, 7, 10, 9, 5, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Decl`. +pub mod decl { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="6")] + Config(super::Config), + #[prost(message, tag="1")] + Data(super::Data), + #[prost(message, tag="3")] + Database(super::Database), + #[prost(message, tag="4")] + Enum(super::Enum), + #[prost(message, tag="7")] + Secret(super::Secret), + #[prost(message, tag="10")] + Subscription(super::Subscription), + #[prost(message, tag="9")] + Topic(super::Topic), + #[prost(message, tag="5")] + TypeAlias(super::TypeAlias), + #[prost(message, tag="2")] + Verb(super::Verb), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Enum { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="6")] + pub variants: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct EnumVariant { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub value: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Field { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="3")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="5")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Float { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathComponent { + #[prost(oneof="ingress_path_component::Value", tags="1, 2")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `IngressPathComponent`. +pub mod ingress_path_component { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="1")] + IngressPathLiteral(super::IngressPathLiteral), + #[prost(message, tag="2")] + IngressPathParameter(super::IngressPathParameter), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathLiteral { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub text: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IngressPathParameter { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Int { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IntValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(int64, tag="2")] + pub value: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Map { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub key: ::core::option::Option<::prost::alloc::boxed::Box>, + #[prost(message, optional, boxed, tag="3")] + pub value: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Metadata { + #[prost(oneof="metadata::Value", tags="5, 1, 10, 3, 4, 9, 2, 12, 6, 11, 7, 8")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Metadata`. +pub mod metadata { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="5")] + Alias(super::MetadataAlias), + #[prost(message, tag="1")] + Calls(super::MetadataCalls), + #[prost(message, tag="10")] + Config(super::MetadataConfig), + #[prost(message, tag="3")] + CronJob(super::MetadataCronJob), + #[prost(message, tag="4")] + Databases(super::MetadataDatabases), + #[prost(message, tag="9")] + Encoding(super::MetadataEncoding), + #[prost(message, tag="2")] + Ingress(super::MetadataIngress), + #[prost(message, tag="12")] + Publisher(super::MetadataPublisher), + #[prost(message, tag="6")] + Retry(super::MetadataRetry), + #[prost(message, tag="11")] + Secrets(super::MetadataSecrets), + #[prost(message, tag="7")] + Subscriber(super::MetadataSubscriber), + #[prost(message, tag="8")] + TypeMap(super::MetadataTypeMap), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataAlias { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(enumeration="AliasKind", tag="2")] + pub kind: i32, + #[prost(string, tag="3")] + pub alias: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataCalls { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub calls: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataConfig { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub config: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataCronJob { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub cron: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataDatabases { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub calls: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataEncoding { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub r#type: ::prost::alloc::string::String, + #[prost(bool, tag="3")] + pub lenient: bool, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataIngress { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub method: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub path: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataPublisher { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub topics: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataRetry { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(int64, optional, tag="2")] + pub count: ::core::option::Option, + #[prost(string, tag="3")] + pub min_backoff: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub max_backoff: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub catch: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataSecrets { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub secrets: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataSubscriber { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MetadataTypeMap { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub runtime: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub native_name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Module { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub builtin: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="5")] + pub decls: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleRuntime { + #[prost(message, optional, tag="1")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(string, tag="2")] + pub language: ::prost::alloc::string::String, + #[prost(int32, tag="3")] + pub min_replicas: i32, + #[prost(string, optional, tag="4")] + pub os: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="5")] + pub arch: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, optional, tag="6")] + pub image: ::core::option::Option<::prost::alloc::string::String>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Optional { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, boxed, tag="2")] + pub r#type: ::core::option::Option<::prost::alloc::boxed::Box>, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Position { + #[prost(string, tag="1")] + pub filename: ::prost::alloc::string::String, + #[prost(int64, tag="2")] + pub line: i64, + #[prost(int64, tag="3")] + pub column: i64, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Ref { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="3")] + pub module: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="4")] + pub type_parameters: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Schema { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub modules: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Secret { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub r#type: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct String { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StringValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub value: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Subscription { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="3")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="4")] + pub topic: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Time { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Topic { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub event: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Type { + #[prost(oneof="r#type::Value", tags="9, 7, 5, 4, 2, 1, 8, 12, 11, 3, 6, 10")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Type`. +pub mod r#type { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="9")] + Any(super::Any), + #[prost(message, tag="7")] + Array(::prost::alloc::boxed::Box), + #[prost(message, tag="5")] + Bool(super::Bool), + #[prost(message, tag="4")] + Bytes(super::Bytes), + #[prost(message, tag="2")] + Float(super::Float), + #[prost(message, tag="1")] + Int(super::Int), + #[prost(message, tag="8")] + Map(::prost::alloc::boxed::Box), + #[prost(message, tag="12")] + Optional(::prost::alloc::boxed::Box), + #[prost(message, tag="11")] + Ref(super::Ref), + #[prost(message, tag="3")] + String(super::String), + #[prost(message, tag="6")] + Time(super::Time), + #[prost(message, tag="10")] + Unit(super::Unit), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeAlias { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub r#type: ::core::option::Option, + #[prost(message, repeated, tag="6")] + pub metadata: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeParameter { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, tag="2")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TypeValue { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub value: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Unit { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Value { + #[prost(oneof="value::Value", tags="2, 1, 3")] + pub value: ::core::option::Option, +} +/// Nested message and enum types in `Value`. +pub mod value { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Value { + #[prost(message, tag="2")] + IntValue(super::IntValue), + #[prost(message, tag="1")] + StringValue(super::StringValue), + #[prost(message, tag="3")] + TypeValue(super::TypeValue), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Verb { + #[prost(message, optional, tag="1")] + pub pos: ::core::option::Option, + #[prost(string, repeated, tag="2")] + pub comments: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag="3")] + pub export: bool, + #[prost(string, tag="4")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub request: ::core::option::Option, + #[prost(message, optional, tag="6")] + pub response: ::core::option::Option, + #[prost(message, repeated, tag="7")] + pub metadata: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag="31634")] + pub runtime: ::core::option::Option, +} +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct VerbRuntime { + #[prost(message, optional, tag="1")] + pub create_time: ::core::option::Option<::prost_types::Timestamp>, + #[prost(message, optional, tag="2")] + pub start_time: ::core::option::Option<::prost_types::Timestamp>, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum AliasKind { + Json = 0, +} +impl AliasKind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Json => "ALIAS_KIND_JSON", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "ALIAS_KIND_JSON" => Some(Self::Json), + _ => None, + } + } +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1beta1.provisioner.rs b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1beta1.provisioner.rs new file mode 100644 index 0000000000..5afa82d799 --- /dev/null +++ b/internal/sqlc-gen-ftl/src/protos/xyz.block.ftl.v1beta1.provisioner.rs @@ -0,0 +1,189 @@ +// @generated +// This file is @generated by prost-build. +/// Resource is an abstract resource extracted from FTL Schema. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Resource { + /// id unique within the module + #[prost(string, tag="1")] + pub resource_id: ::prost::alloc::string::String, + #[prost(oneof="resource::Resource", tags="102, 103, 104")] + pub resource: ::core::option::Option, +} +/// Nested message and enum types in `Resource`. +pub mod resource { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Resource { + #[prost(message, tag="102")] + Postgres(super::PostgresResource), + #[prost(message, tag="103")] + Mysql(super::MysqlResource), + #[prost(message, tag="104")] + Module(super::ModuleResource), + } +} +// Resource types +// +// any output created by the provisioner is stored in a field called "output" + +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PostgresResource { + #[prost(message, optional, tag="1")] + pub output: ::core::option::Option, +} +/// Nested message and enum types in `PostgresResource`. +pub mod postgres_resource { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct PostgresResourceOutput { + #[prost(string, tag="1")] + pub read_dsn: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub write_dsn: ::prost::alloc::string::String, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct MysqlResource { + #[prost(message, optional, tag="1")] + pub output: ::core::option::Option, +} +/// Nested message and enum types in `MysqlResource`. +pub mod mysql_resource { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct MysqlResourceOutput { + #[prost(string, tag="1")] + pub read_dsn: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub write_dsn: ::prost::alloc::string::String, + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ModuleResource { + #[prost(message, optional, tag="1")] + pub output: ::core::option::Option, + #[prost(message, optional, tag="2")] + pub schema: ::core::option::Option, + #[prost(message, repeated, tag="3")] + pub artefacts: ::prost::alloc::vec::Vec, + /// Runner labels required to run this deployment. + #[prost(message, optional, tag="4")] + pub labels: ::core::option::Option<::prost_types::Struct>, +} +/// Nested message and enum types in `ModuleResource`. +pub mod module_resource { + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ModuleResourceOutput { + #[prost(string, tag="1")] + pub deployment_key: ::prost::alloc::string::String, + } +} +/// ResourceContext is the context used to create a new resource +/// This includes the direct dependencies of the new resource, that can impact +/// the resource creation. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ResourceContext { + #[prost(message, optional, tag="1")] + pub resource: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub dependencies: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProvisionRequest { + #[prost(string, tag="1")] + pub ftl_cluster_id: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub module: ::prost::alloc::string::String, + /// The resource FTL thinks exists currently + #[prost(message, repeated, tag="3")] + pub existing_resources: ::prost::alloc::vec::Vec, + /// The resource FTL would like to exist after this provisioning run. + /// This includes all new, existing, and changes resources in this change. + #[prost(message, repeated, tag="4")] + pub desired_resources: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ProvisionResponse { + #[prost(string, tag="1")] + pub provisioning_token: ::prost::alloc::string::String, + #[prost(enumeration="provision_response::ProvisionResponseStatus", tag="2")] + pub status: i32, +} +/// Nested message and enum types in `ProvisionResponse`. +pub mod provision_response { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum ProvisionResponseStatus { + Unknown = 0, + Submitted = 1, + } + impl ProvisionResponseStatus { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unknown => "UNKNOWN", + Self::Submitted => "SUBMITTED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "UNKNOWN" => Some(Self::Unknown), + "SUBMITTED" => Some(Self::Submitted), + _ => None, + } + } + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatusRequest { + #[prost(string, tag="1")] + pub provisioning_token: ::prost::alloc::string::String, + /// The set of desired_resources used to initiate this provisioning request + /// We need this as input here, so we can populate any resource fields in them + /// when the provisioning finishes + #[prost(message, repeated, tag="2")] + pub desired_resources: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatusResponse { + #[prost(oneof="status_response::Status", tags="1, 2")] + pub status: ::core::option::Option, +} +/// Nested message and enum types in `StatusResponse`. +pub mod status_response { + #[derive(Clone, Copy, PartialEq, ::prost::Message)] + pub struct ProvisioningRunning { + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ProvisioningFailed { + #[prost(string, tag="1")] + pub error_message: ::prost::alloc::string::String, + } + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct ProvisioningSuccess { + /// Some fields in the resources might have been populated + /// during the provisioning. The new state is returned here + #[prost(message, repeated, tag="1")] + pub updated_resources: ::prost::alloc::vec::Vec, + } + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Status { + #[prost(message, tag="1")] + Running(ProvisioningRunning), + #[prost(message, tag="2")] + Success(ProvisioningSuccess), + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PlanRequest { + #[prost(message, optional, tag="1")] + pub provisioning: ::core::option::Option, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PlanResponse { + /// a detailed, implementation specific, plan of changes this deployment would do + #[prost(string, tag="1")] + pub plan: ::prost::alloc::string::String, +} +// @@protoc_insertion_point(module) diff --git a/internal/sqlc-gen-ftl/test/sqlc_gen_ftl_test.rs b/internal/sqlc-gen-ftl/test/sqlc_gen_ftl_test.rs new file mode 100644 index 0000000000..daa95ccfb4 --- /dev/null +++ b/internal/sqlc-gen-ftl/test/sqlc_gen_ftl_test.rs @@ -0,0 +1,279 @@ +use std::process::Command; +use std::path::PathBuf; +use std::fs; +use prost::Message; +use tempfile::TempDir; +use sha2::{Sha256, Digest}; + +#[path = "../src/plugin/mod.rs"] +mod plugin; +#[path = "../src/protos/mod.rs"] +mod protos; + +use protos::schemapb; + +fn build_wasm() -> Result<(), Box> { + let status = Command::new("just") + .arg("build-sqlc-gen-ftl") + .status()?; + + if !status.success() { + return Err("Failed to build WASM".into()); + } + Ok(()) +} + +fn expected_module_schema() -> schemapb::Module { + schemapb::Module { + name: "echo".to_string(), + builtin: false, + runtime: None, + comments: vec![], + pos: None, + decls: vec![ + schemapb::Decl { + value: Some(schemapb::decl::Value::Data(schemapb::Data { + name: "GetUserByIDRequest".to_string(), + export: false, + type_parameters: vec![], + fields: vec![ + schemapb::Field { + name: "id".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::Int(schemapb::Int { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + } + ], + pos: None, + comments: vec![], + metadata: vec![], + })), + }, + schemapb::Decl { + value: Some(schemapb::decl::Value::Data(schemapb::Data { + name: "GetUserByIDResponse".to_string(), + export: false, + type_parameters: vec![], + fields: vec![ + schemapb::Field { + name: "id".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::Int(schemapb::Int { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + }, + schemapb::Field { + name: "name".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::String(schemapb::String { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + }, + schemapb::Field { + name: "email".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::String(schemapb::String { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + } + ], + pos: None, + comments: vec![], + metadata: vec![], + })), + }, + schemapb::Decl { + value: Some(schemapb::decl::Value::Verb(schemapb::Verb { + name: "GetUserByID".to_string(), + export: false, + runtime: None, + request: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::Ref(schemapb::Ref { + module: "echo".to_string(), + name: "GetUserByIDRequest".to_string(), + pos: None, + type_parameters: vec![], + })) + }), + response: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::Ref(schemapb::Ref { + module: "echo".to_string(), + name: "GetUserByIDResponse".to_string(), + pos: None, + type_parameters: vec![], + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + })), + }, + schemapb::Decl { + value: Some(schemapb::decl::Value::Data(schemapb::Data { + name: "CreateUserRequest".to_string(), + export: false, + type_parameters: vec![], + fields: vec![ + schemapb::Field { + name: "name".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::String(schemapb::String { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + }, + schemapb::Field { + name: "email".to_string(), + r#type: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::String(schemapb::String { + pos: None, + })) + }), + pos: None, + comments: vec![], + metadata: vec![], + } + ], + pos: None, + comments: vec![], + metadata: vec![], + })), + }, + schemapb::Decl { + value: Some(schemapb::decl::Value::Verb(schemapb::Verb { + name: "CreateUser".to_string(), + export: false, + runtime: None, + request: Some(schemapb::Type { + value: Some(schemapb::r#type::Value::Ref(schemapb::Ref { + module: "echo".to_string(), + name: "CreateUserRequest".to_string(), + pos: None, + type_parameters: vec![], + })) + }), + response: None, + pos: None, + comments: vec![], + metadata: vec![], + })), + }, + ], + } +} + +fn get_sqlc_config(wasm_path: &PathBuf) -> Result> { + let wasm_contents = fs::read(wasm_path)?; + let mut hasher = Sha256::new(); + hasher.update(&wasm_contents); + let sha256_hash = hex::encode(hasher.finalize()); + + Ok(format!( + r#"version: '2' +plugins: +- name: ftl + wasm: + url: file://sqlc-gen-ftl.wasm + sha256: {} +sql: +- schema: schema.sql + queries: queries.sql + engine: postgresql + codegen: + - out: gen + plugin: ftl + options: + module: echo"#, + sha256_hash, + )) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg_attr(not(feature = "ci"), ignore)] + fn test_wasm_generate() -> Result<(), Box> { + if let Err(e) = build_wasm() { + return Err(format!("Failed to build WASM: {}", e).into()); + } + + let temp_dir = TempDir::new()?; + let gen_dir = temp_dir.path().join("gen"); + std::fs::create_dir(&gen_dir)?; + + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let test_dir = root_dir.join("test"); + let wasm_path = temp_dir.path().join("sqlc-gen-ftl.wasm"); + + std::fs::copy( + test_dir.join("testdata/schema.sql"), + temp_dir.path().join("schema.sql") + )?; + std::fs::copy( + test_dir.join("testdata/queries.sql"), + temp_dir.path().join("queries.sql") + )?; + std::fs::copy( + root_dir.join("dist/sqlc-gen-ftl.wasm"), + &wasm_path + )?; + + let config_contents = get_sqlc_config(&wasm_path)?; + let config_path = temp_dir.path().join("sqlc.yaml"); + std::fs::write(&config_path, config_contents)?; + + let output = Command::new("sqlc") + .arg("generate") + .arg("--file") + .arg(&config_path) + .current_dir(temp_dir.path()) + .env("SQLC_VERSION", "dev") + .env("SQLCDEBUG", "true") + .output()?; + + if !output.status.success() { + return Err(format!( + "sqlc generate failed with status: {}\nstderr: {}", + output.status, + String::from_utf8_lossy(&output.stderr) + ).into()); + } + + let pb_contents = std::fs::read(gen_dir.join("queries.pb"))?; + let actual_module = schemapb::Module::decode(&*pb_contents)?; + let expected_module = expected_module_schema(); + + assert_eq!( + &actual_module, + &expected_module, + "Schema mismatch.\nActual: {:#?}\nExpected: {:#?}", + actual_module, + expected_module + ); + + Ok(()) + } +} + diff --git a/internal/sqlc-gen-ftl/test/testdata/queries.sql b/internal/sqlc-gen-ftl/test/testdata/queries.sql new file mode 100644 index 0000000000..78dc04a589 --- /dev/null +++ b/internal/sqlc-gen-ftl/test/testdata/queries.sql @@ -0,0 +1,5 @@ +-- name: GetUserByID :one +SELECT id, name, email FROM users WHERE id = $1; + +-- name: CreateUser :exec +INSERT INTO users (name, email) VALUES ($1, $2); diff --git a/internal/sqlc-gen-ftl/test/testdata/schema.sql b/internal/sqlc-gen-ftl/test/testdata/schema.sql new file mode 100644 index 0000000000..7caa7bce2c --- /dev/null +++ b/internal/sqlc-gen-ftl/test/testdata/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + email TEXT +); diff --git a/scripts/autofmt b/scripts/autofmt index de66eeab7d..bdea7b4d29 100755 --- a/scripts/autofmt +++ b/scripts/autofmt @@ -24,6 +24,8 @@ find backend/protos \( -name '*.pb.go' -o -name '*.connect.go' \) -print0 | xarg just pnpm-install +just rust-toolchain-install + (cd backend/protos && buf generate) echo "Formatting TypeScript..."