diff --git a/Cargo.lock b/Cargo.lock index 3807895c0..8b881be77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5748,9 +5748,9 @@ dependencies = [ [[package]] name = "yerpc" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30fc983d32883ecb563227a2dcdcbe8567decd9c533b5ecca7e3099e2f7d4c96" +checksum = "75b5547af776328f66a5476ea3b7c0789e6fed164eb32d1a2122cfb39ffa505d" dependencies = [ "anyhow", "async-channel", @@ -5771,9 +5771,9 @@ dependencies = [ [[package]] name = "yerpc_derive" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6b8ce490e8719fe84d7d80ad4d58572b2ea9d7a83d156f6afd6ab3ad5cfb94" +checksum = "f321bb5f728fb066af06c5a994e4375f1f8b054ee6d650766f0bd68dfa4faefe" dependencies = [ "convert_case 0.5.0", "darling 0.14.4", diff --git a/deltachat-jsonrpc/Cargo.toml b/deltachat-jsonrpc/Cargo.toml index 925086448..c17f3c4d4 100644 --- a/deltachat-jsonrpc/Cargo.toml +++ b/deltachat-jsonrpc/Cargo.toml @@ -22,7 +22,7 @@ log = "0.4" async-channel = { version = "1.8.0" } futures = { version = "0.3.28" } serde_json = "1.0.99" -yerpc = { version = "0.5.1", features = ["anyhow_expose", "openrpc"] } +yerpc = { version = "0.5.2", features = ["anyhow_expose", "openrpc"] } typescript-type-def = { version = "0.5.5", features = ["json_value"] } tokio = { version = "1.29.1" } sanitize-filename = "0.4" diff --git a/deltachat-jsonrpc/src/api/mod.rs b/deltachat-jsonrpc/src/api/mod.rs index d9b6db8aa..5768d6eb5 100644 --- a/deltachat-jsonrpc/src/api/mod.rs +++ b/deltachat-jsonrpc/src/api/mod.rs @@ -142,11 +142,7 @@ impl CommandApi { } } -#[rpc( - all_positional, - ts_outdir = "typescript/generated", - openrpc_outdir = "openrpc" -)] +#[rpc(all_positional, ts_outdir = "typescript/generated")] impl CommandApi { /// Test function. async fn sleep(&self, delay: f64) { diff --git a/deltachat-rpc-client/tests/test_something.py b/deltachat-rpc-client/tests/test_something.py index 9a498470a..77fdb0d3b 100644 --- a/deltachat-rpc-client/tests/test_something.py +++ b/deltachat-rpc-client/tests/test_something.py @@ -1,4 +1,6 @@ import asyncio +import json +import subprocess from unittest.mock import MagicMock import pytest @@ -357,3 +359,11 @@ async def test_import_export(acfactory, tmp_path) -> None: await alice2.import_backup(files[0]) assert await alice2.manager.get_system_info() + + +def test_openrpc_command_line() -> None: + """Test that "deltachat-rpc-server --openrpc" command returns an OpenRPC specification.""" + out = subprocess.run(["deltachat-rpc-server", "--openrpc"], capture_output=True).stdout + openrpc = json.loads(out) + assert "openrpc" in openrpc + assert "methods" in openrpc diff --git a/deltachat-rpc-server/Cargo.toml b/deltachat-rpc-server/Cargo.toml index 9560a0f22..03a480c5a 100644 --- a/deltachat-rpc-server/Cargo.toml +++ b/deltachat-rpc-server/Cargo.toml @@ -21,7 +21,7 @@ serde_json = "1.0.99" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.29.1", features = ["io-std"] } tokio-util = "0.7.8" -yerpc = { version = "0.5.1", features = ["anyhow_expose"] } +yerpc = { version = "0.5.2", features = ["anyhow_expose", "openrpc"] } [features] default = ["vendored"] diff --git a/deltachat-rpc-server/README.md b/deltachat-rpc-server/README.md index 2027072a5..be8c0c562 100644 --- a/deltachat-rpc-server/README.md +++ b/deltachat-rpc-server/README.md @@ -32,3 +32,6 @@ languages other than Rust, for example: 1. Python: https://github.com/deltachat/deltachat-core-rust/tree/master/deltachat-rpc-client/ 2. Go: https://github.com/deltachat/deltachat-rpc-client-go/ + +Run `deltachat-rpc-server --version` to check the version of the server. +Run `deltachat-rpc-server --openrpc` to get [OpenRPC](https://open-rpc.org/) specification of the provided JSON-RPC API. diff --git a/deltachat-rpc-server/src/main.rs b/deltachat-rpc-server/src/main.rs index 1a3049f85..4be58760b 100644 --- a/deltachat-rpc-server/src/main.rs +++ b/deltachat-rpc-server/src/main.rs @@ -10,6 +10,7 @@ use deltachat::constants::DC_VERSION_STR; use deltachat_jsonrpc::api::{Accounts, CommandApi}; use futures_lite::stream::StreamExt; use tokio::io::{self, AsyncBufReadExt, BufReader}; +use yerpc::RpcServer as _; #[cfg(target_family = "unix")] use tokio::signal::unix as signal_unix; @@ -39,6 +40,12 @@ async fn main_impl() -> Result<()> { } eprintln!("{}", &*DC_VERSION_STR); return Ok(()); + } else if first_arg.to_str() == Some("--openrpc") { + if let Some(arg) = args.next() { + return Err(anyhow!("Unrecognized argument {:?}", arg)); + } + println!("{}", CommandApi::openrpc_specification()?); + return Ok(()); } else { return Err(anyhow!("Unrecognized option {:?}", first_arg)); }