@smbcloud / cli / commits / 7e9456b

Refactor account networking and add WASM support

- Move account-related networking to smbcloud-networking-account - Add smbcloud-networking-account-wasm crate for WASM bindings - Update CLI to use new account networking module - Add me endpoint to smbcloud-networking-account - Update dependencies and workspace members - Expose Environment enum to WASM - Bump smbcloud-networking-account to version 0.3.0

Seto Elkahfi committed Jul 26, 2025 at 20:15 UTC 7e9456b8af45987c753b2c09f9635e5014ea6541
17 files changed +128 -62
Cargo.lock
+30
@@ -1196,6 +1196,7 @@ dependencies = [
1196 "serde",
1197 "serde_json",
1198 "smbcloud-model",
1199 + "wasm-bindgen",
1200 ]
1201
1202 [[package]]
@@ -1768,6 +1769,17 @@ dependencies = [
1769 "serde_derive",
1770 ]
1771
1772 +[[package]]
1773 +name = "serde-wasm-bindgen"
1774 +version = "0.6.5"
1775 +source = "registry+https://github.com/rust-lang/crates.io-index"
1776 +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
1777 +dependencies = [
1778 + "js-sys",
1779 + "serde",
1780 + "wasm-bindgen",
1781 +]
1782 +
1783 [[package]]
1784 name = "serde_derive"
1785 version = "1.0.219"
@@ -1906,6 +1918,7 @@ dependencies = [
1918 "serde_repr",
1919 "smbcloud-model",
1920 "smbcloud-networking",
1921 + "smbcloud-networking-account",
1922 "smbcloud-networking-project",
1923 "smbcloud-utils",
1924 "spinners",
@@ -1944,12 +1957,29 @@ dependencies = [
1957
1958 [[package]]
1959 name = "smbcloud-networking-account"
1960 +version = "0.3.0"
1961 +dependencies = [
1962 + "network",
1963 + "reqwest",
1964 + "smbcloud-model",
1965 + "smbcloud-networking",
1966 +]
1967 +
1968 +[[package]]
1969 +name = "smbcloud-networking-account-wasm"
1970 version = "0.1.0"
1971 dependencies = [
1972 "network",
1973 "reqwest",
1974 + "serde",
1975 + "serde-wasm-bindgen",
1976 + "serde_json",
1977 + "serde_repr",
1978 "smbcloud-model",
1979 "smbcloud-networking",
1980 + "thiserror 2.0.12",
1981 + "wasm-bindgen",
1982 + "wasm-bindgen-futures",
1983 ]
1984
1985 [[package]]
Cargo.toml
+3
@@ -7,6 +7,7 @@ members = [
7 "crates/smbcloud-model",
8 "crates/smbcloud-networking",
9 "crates/smbcloud-networking-account",
10 + "crates/smbcloud-networking-account-wasm",
11 "crates/smbcloud-networking-project",
12 "crates/smbcloud-utils",
13 ]
@@ -34,6 +35,7 @@ serde_repr = "0.1"
35 network = { version = "0.1", path = "crates/network" }
36 smbcloud-model = { version = "0.3", path = "crates/smbcloud-model" }
37 smbcloud-networking = { version = "0.3", path = "crates/smbcloud-networking" }
38 +smbcloud-networking-account = { version = "0.3", path = "crates/smbcloud-networking-account" }
39 smbcloud-networking-project = { version = "0.3", path = "crates/smbcloud-networking-project" }
40 smbcloud-utils = { version = "0.3", path = "crates/smbcloud-utils" }
41 spinners = "4.1.0"
@@ -48,3 +50,4 @@ tracing = "0.1.35"
50 tracing-bunyan-formatter = "0.3.3"
51 tracing-subscriber = "0.3.14"
52 url-builder = "0.1.1"
53 +wasm-bindgen = "0.2"
crates/cli/Cargo.toml
+1
@@ -42,6 +42,7 @@ serde_repr = { workspace = true }
42 network = { workspace = true }
43 smbcloud-model = { workspace = true }
44 smbcloud-networking = { workspace = true }
45 +smbcloud-networking-account = { workspace = true }
46 smbcloud-networking-project = { workspace = true }
47 smbcloud-utils = { workspace = true }
48 spinners = { workspace = true }
crates/cli/src/account/me/mod.rs
+10 -33
@@ -4,11 +4,10 @@ use crate::{
4 cli::CommandResult,
5 ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
6 };
7 -use anyhow::{anyhow, Result};
7 +use anyhow::Result;
8 use network::environment::Environment;
9 -use reqwest::{Client, StatusCode};
9 use smbcloud_model::account::User;
11 -use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
10 +use smbcloud_networking_account::me::me;
11 use spinners::Spinner;
12 use tabled::{Table, Tabled};
13
@@ -50,7 +49,8 @@ pub async fn process_me(env: Environment) -> Result<CommandResult> {
49 spinners::Spinners::SimpleDotsScrolling,
50 succeed_message("Loading"),
51 );
53 - match me(env).await {
52 + let token = get_smb_token(env).await?;
53 + match me(env, &token).await {
54 Ok(user) => {
55 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Loaded."));
56 show_user(&user);
@@ -64,35 +64,12 @@ pub async fn process_me(env: Environment) -> Result<CommandResult> {
64 })
65 }
66 Err(e) => {
67 - spinner.stop_and_persist(&fail_symbol(), fail_message(&e.to_string()));
68 - Err(e)
69 - }
70 - }
71 -}
72 -
73 -pub async fn me(env: Environment) -> Result<User> {
74 - let token = get_smb_token(env).await?;
75 -
76 - let response = Client::new()
77 - .get(build_smb_info_url(env))
78 - .header("Authorization", token)
79 - .header("Accept", "application/json")
80 - .header("Content-Type", "application/x-www-form-urlencoded")
81 - .send()
82 - .await?;
83 -
84 - match response.status() {
85 - StatusCode::OK => {
86 - let user: User = response.json().await?;
87 - Ok(user)
67 + println!("Error: {e:#?}");
68 + Ok(CommandResult {
69 + spinner,
70 + symbol: fail_symbol(),
71 + msg: fail_message("Failed to get all projects."),
72 + })
73 }
89 - StatusCode::UNAUTHORIZED => Err(anyhow!("Invalid token. Please logout first.")),
90 - _ => Err(anyhow!("Error while requesting your information.")),
74 }
75 }
93 -
94 -fn build_smb_info_url(env: Environment) -> String {
95 - let mut url_builder = smb_base_url_builder(env);
96 - url_builder.add_route(PATH_USERS_ME);
97 - url_builder.build()
98 -}
crates/cli/src/deploy/mod.rs
+3 -2
@@ -5,7 +5,7 @@ mod setup;
5
6 use crate::token::get_smb_token;
7 use crate::{
8 - account::{lib::is_logged_in, login::process_login, me::me},
8 + account::{lib::is_logged_in, login::process_login},
9 cli::CommandResult,
10 deploy::config::check_project,
11 project::runner::detect_runner,
@@ -18,6 +18,7 @@ use git2::{PushOptions, RemoteCallbacks, Repository};
18 use network::environment::Environment;
19 use remote_messages::{build_next_app, start_server};
20 use smbcloud_model::project::{DeploymentPayload, DeploymentStatus};
21 +use smbcloud_networking_account::me::me;
22 use smbcloud_networking_project::{
23 crud_project_deployment_create::create_deployment, crud_project_deployment_update::update,
24 };
@@ -98,7 +99,7 @@ pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
99
100 let created_deployment =
101 create_deployment(env, &access_token, config.project.id, payload).await?;
101 - let user = me(env).await?;
102 + let user = me(env, &access_token).await?;
103
104 let mut push_opts = PushOptions::new();
105 let mut callbacks = RemoteCallbacks::new();
crates/network/Cargo.toml
+1
@@ -13,3 +13,4 @@ reqwest = { workspace = true, features = ["json"] }
13 serde = { workspace = true, features = ["derive"] }
14 serde_json = { workspace = true }
15 smbcloud-model = { workspace = true }
16 +wasm-bindgen = { workspace = true }
crates/network/src/environment.rs
+3
@@ -1,4 +1,7 @@
1 +use wasm_bindgen::prelude::wasm_bindgen;
2 +
3 #[derive(clap::ValueEnum, Clone, Copy)]
4 +#[wasm_bindgen]
5 pub enum Environment {
6 Dev,
7 Production,
crates/smbcloud-networking-account-wasm/Cargo.toml new
+20
@@ -0,0 +1,20 @@
1 +[package]
2 +name = "smbcloud-networking-account-wasm"
3 +version = "0.1.0"
4 +edition = "2024"
5 +
6 +[lib]
7 +crate-type = ["cdylib", "rlib"]
8 +
9 +[dependencies]
10 +network = { workspace = true }
11 +smbcloud-networking = { workspace = true }
12 +smbcloud-model = { workspace = true }
13 +reqwest = { workspace = true, features = ["json"] }
14 +wasm-bindgen = { workspace = true }
15 +wasm-bindgen-futures = "0.4.50"
16 +serde = { workspace = true, features = ["derive"] }
17 +serde_json = { workspace = true }
18 +serde_repr = { workspace = true }
19 +thiserror = { workspace = true }
20 +serde-wasm-bindgen = "=0.6.5"
crates/smbcloud-networking-account-wasm/src/lib.rs new
+2
@@ -0,0 +1,2 @@
1 +pub mod login;
2 +pub(crate) mod url_builder;
crates/smbcloud-networking-account-wasm/src/login.rs new
+32
@@ -0,0 +1,32 @@
1 +use crate::url_builder::build_smb_login_url;
2 +use network::environment::Environment;
3 +use network::network::request;
4 +use reqwest::Client;
5 +use serde::Serialize;
6 +use smbcloud_model::login::LoginResult;
7 +use smbcloud_networking::constants::SMB_USER_AGENT;
8 +use wasm_bindgen::JsValue;
9 +use wasm_bindgen::prelude::wasm_bindgen;
10 +
11 +#[derive(Debug, Serialize)]
12 +pub struct LoginParams {
13 + pub username: String,
14 + pub password: String,
15 +}
16 +
17 +#[wasm_bindgen]
18 +pub async fn login(
19 + env: Environment,
20 + username: String,
21 + password: String,
22 +) -> Result<JsValue, JsValue> {
23 + let login_params = LoginParams { username, password };
24 + let builder = Client::new()
25 + .post(build_smb_login_url(env))
26 + .json(&login_params)
27 + .header("User-agent", SMB_USER_AGENT);
28 + match request::<LoginResult>(builder).await {
29 + Ok(response) => Ok(serde_wasm_bindgen::to_value(&response)?),
30 + Err(error) => Err(serde_wasm_bindgen::to_value(&error)?),
31 + }
32 +}
crates/smbcloud-networking-account-wasm/src/url_builder.rs renamed
crates/smbcloud-networking-account/.gitignore new
+1
@@ -0,0 +1 @@
1 +/target
crates/smbcloud-networking-account/Cargo.toml
+1 -4
@@ -1,11 +1,8 @@
1 [package]
2 name = "smbcloud-networking-account"
3 -version = "0.1.0"
3 +version = "0.3.0"
4 edition = "2024"
5
6 -[lib]
7 -crate-type = ["cdylib", "rlib"]
8 -
6 [dependencies]
7 network = { workspace = true }
8 smbcloud-networking = { workspace = true }
crates/smbcloud-networking-account/src/lib.rs
+1 -1
@@ -1,2 +1,2 @@
1 pub mod login;
2 -pub(crate) mod url_builder;
2 +pub mod me;
crates/smbcloud-networking-account/src/login.rs
-19
@@ -1,20 +1 @@
1 -use crate::url_builder::build_smb_login_url;
2 -use network::environment::Environment;
3 -use network::network::request;
4 -use reqwest::Client;
5 -use smbcloud_model::{
6 - error_codes::ErrorResponse,
7 - login::{LoginParams, LoginResult},
8 -};
9 -use smbcloud_networking::constants::SMB_USER_AGENT;
1
11 -pub async fn login(
12 - env: Environment,
13 - login_params: LoginParams,
14 -) -> Result<LoginResult, ErrorResponse> {
15 - let builder = Client::new()
16 - .post(build_smb_login_url(env))
17 - .json(&login_params)
18 - .header("User-agent", SMB_USER_AGENT);
19 - request(builder).await
20 -}
crates/smbcloud-networking-account/src/me.rs new
+20
@@ -0,0 +1,20 @@
1 +use network::{environment::Environment, network::request};
2 +use reqwest::Client;
3 +use smbcloud_model::account::User;
4 +use smbcloud_model::error_codes::ErrorResponse;
5 +use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
6 +
7 +pub async fn me(env: Environment, access_token: &str) -> Result<User, ErrorResponse> {
8 + let builder = Client::new()
9 + .get(build_smb_info_url(env))
10 + .header("Authorization", access_token)
11 + .header("Accept", "application/json")
12 + .header("Content-Type", "application/x-www-form-urlencoded");
13 + request(builder).await
14 +}
15 +
16 +fn build_smb_info_url(env: Environment) -> String {
17 + let mut url_builder = smb_base_url_builder(env);
18 + url_builder.add_route(PATH_USERS_ME);
19 + url_builder.build()
20 +}
crates/smbcloud-networking-project/Cargo.toml
-3
@@ -17,9 +17,6 @@ categories = [
17 ]
18 readme = "README.md"
19
20 -[lib]
21 -crate-type = ["cdylib", "rlib"]
22 -
20 [dependencies]
21 anyhow = { workspace = true }
22 async-trait = { workspace = true, optional = true }