From 9796dfc54843b8e4b49adf0d76eddb67f703ac8e 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 | 12 + .gitignore | 5 +- Justfile | 24 +- backend/protos/buf.gen.yaml | 4 + bin/.rust-1.83.0.pkg | 1 + bin/.rust-src-1.83.0.pkg | 1 + bin/.rustup-1.25.2.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 + internal/sqlc-gen-ftl/Cargo.lock | 1721 +++++++++++++++++ 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 + 48 files changed, 7183 insertions(+), 3 deletions(-) create mode 120000 bin/.rust-1.83.0.pkg create mode 120000 bin/.rust-src-1.83.0.pkg create mode 120000 bin/.rustup-1.25.2.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 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..746847a0e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,18 @@ 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: 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..d574bdb1c8 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 + @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,16 @@ 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 +cargo-install: + @mk internal/sqlc-gen-ftl/target : internal/sqlc-gen-ftl/Cargo.toml -- \ + "cd internal/sqlc-gen-ftl && \ + 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 +233,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 cargo-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-1.83.0.pkg b/bin/.rust-1.83.0.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.rust-1.83.0.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file 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/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/internal/sqlc-gen-ftl/Cargo.lock b/internal/sqlc-gen-ftl/Cargo.lock new file mode 100644 index 0000000000..7119565b86 --- /dev/null +++ b/internal/sqlc-gen-ftl/Cargo.lock @@ -0,0 +1,1721 @@ +# 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 = "protoc-gen-prost-crate" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244ae05ca59e1345b7ccec8dc2eb34ca99538dd5065e2d625910fceabdc3b31e" +dependencies = [ + "once_cell", + "prost", + "prost-build", + "prost-types", + "protoc-gen-prost", + "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-crate", + "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..4914397ce4 --- /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", default-features = false, features = ["std"] } +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..23ddcaae81ccab9d01dfec501428a16398dd11e8 GIT binary patch literal 168600 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 z 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 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..e0f52abbe0 --- /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: http://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..1e85c9bd06 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 cargo-install + (cd backend/protos && buf generate) echo "Formatting TypeScript..."