From aea7261bbfe2710e246c50e96be085201226a5d7 Mon Sep 17 00:00:00 2001 From: Owen Nelson Date: Mon, 6 Jan 2025 15:19:30 -0800 Subject: [PATCH] CLI: update codegen for optional request bodies For the API calls that require a body but all the fields are technically optional, the ideal case is to allow the CLI command to be invoked without a body argument at all. This diff wraps the `JsonOf` fields in this situation with `Option` to this effect. The generator template changes were "basic" in so much as the `Option`-wrapping happens uniformally for cases where passing nothing isn't especially useful (e.g. `PATCH` request). With some additional special-casing, we can probably make those required arguments, but for now they are optional. --- svix-cli/src/cmds/api/application.rs | 9 +++++++-- svix-cli/src/cmds/api/authentication.rs | 12 ++++++++---- svix-cli/src/cmds/api/endpoint.rs | 24 ++++++++++++++++++------ svix-cli/src/cmds/api/event_type.rs | 13 +++++++++---- svix-cli/src/json.rs | 6 +++--- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/svix-cli/src/cmds/api/application.rs b/svix-cli/src/cmds/api/application.rs index 6d42d7df0..ab5d49454 100644 --- a/svix-cli/src/cmds/api/application.rs +++ b/svix-cli/src/cmds/api/application.rs @@ -65,7 +65,7 @@ pub enum ApplicationCommands { /// Partially update an application. Patch { id: String, - application_patch: JsonOf, + application_patch: Option>, }, } @@ -110,7 +110,12 @@ impl ApplicationCommands { } => { let resp = client .application() - .patch(id, application_patch.into_inner()) + .patch( + id, + application_patch + .map(|x| x.into_inner()) + .unwrap_or_default(), + ) .await?; crate::json::print_json_output(&resp, color_mode)?; } diff --git a/svix-cli/src/cmds/api/authentication.rs b/svix-cli/src/cmds/api/authentication.rs index 81a21cb4a..a9ec402c2 100644 --- a/svix-cli/src/cmds/api/authentication.rs +++ b/svix-cli/src/cmds/api/authentication.rs @@ -16,14 +16,14 @@ pub enum AuthenticationCommands { /// Use this function to get magic links (and authentication codes) for connecting your users to the Consumer Application Portal. AppPortalAccess { app_id: String, - app_portal_access_in: JsonOf, + app_portal_access_in: Option>, #[clap(flatten)] post_options: Option, }, /// Expire all of the tokens associated with a specific application. ExpireAll { app_id: String, - application_token_expire_in: JsonOf, + application_token_expire_in: Option>, #[clap(flatten)] post_options: Option, }, @@ -52,7 +52,9 @@ impl AuthenticationCommands { .authentication() .app_portal_access( app_id, - app_portal_access_in.into_inner(), + app_portal_access_in + .map(|x| x.into_inner()) + .unwrap_or_default(), post_options.map(Into::into), ) .await?; @@ -67,7 +69,9 @@ impl AuthenticationCommands { .authentication() .expire_all( app_id, - application_token_expire_in.into_inner(), + application_token_expire_in + .map(|x| x.into_inner()) + .unwrap_or_default(), post_options.map(Into::into), ) .await?; diff --git a/svix-cli/src/cmds/api/endpoint.rs b/svix-cli/src/cmds/api/endpoint.rs index e9c5ef876..a8394f0a2 100644 --- a/svix-cli/src/cmds/api/endpoint.rs +++ b/svix-cli/src/cmds/api/endpoint.rs @@ -92,7 +92,7 @@ pub enum EndpointCommands { Patch { app_id: String, id: String, - endpoint_patch: JsonOf, + endpoint_patch: Option>, }, /// Get the additional headers to be sent with the webhook. GetHeaders { app_id: String, id: String }, @@ -138,7 +138,7 @@ pub enum EndpointCommands { RotateSecret { app_id: String, id: String, - endpoint_secret_rotate_in: JsonOf, + endpoint_secret_rotate_in: Option>, }, /// Send an example message for an event. SendExample { @@ -162,7 +162,7 @@ pub enum EndpointCommands { TransformationPartialUpdate { app_id: String, id: String, - endpoint_transformation_in: JsonOf, + endpoint_transformation_in: Option>, }, } @@ -217,7 +217,11 @@ impl EndpointCommands { } => { let resp = client .endpoint() - .patch(app_id, id, endpoint_patch.into_inner()) + .patch( + app_id, + id, + endpoint_patch.map(|x| x.into_inner()).unwrap_or_default(), + ) .await?; crate::json::print_json_output(&resp, color_mode)?; } @@ -284,7 +288,13 @@ impl EndpointCommands { } => { client .endpoint() - .rotate_secret(app_id, id, endpoint_secret_rotate_in.into_inner()) + .rotate_secret( + app_id, + id, + endpoint_secret_rotate_in + .map(|x| x.into_inner()) + .unwrap_or_default(), + ) .await?; } Self::SendExample { @@ -329,7 +339,9 @@ impl EndpointCommands { .transformation_partial_update( app_id, id, - endpoint_transformation_in.into_inner(), + endpoint_transformation_in + .map(|x| x.into_inner()) + .unwrap_or_default(), ) .await?; } diff --git a/svix-cli/src/cmds/api/event_type.rs b/svix-cli/src/cmds/api/event_type.rs index d9df27bf2..81122a785 100644 --- a/svix-cli/src/cmds/api/event_type.rs +++ b/svix-cli/src/cmds/api/event_type.rs @@ -73,7 +73,7 @@ pub enum EventTypeCommands { /// The importer will convert all webhooks found in the either the `webhooks` or `x-webhooks` /// top-level. ImportOpenapi { - event_type_import_open_api_in: JsonOf, + event_type_import_open_api_in: Option>, #[clap(flatten)] post_options: Option, }, @@ -99,7 +99,7 @@ pub enum EventTypeCommands { /// Partially update an event type. Patch { event_type_name: String, - event_type_patch: JsonOf, + event_type_patch: Option>, }, } @@ -131,7 +131,9 @@ impl EventTypeCommands { let resp = client .event_type() .import_openapi( - event_type_import_open_api_in.into_inner(), + event_type_import_open_api_in + .map(|x| x.into_inner()) + .unwrap_or_default(), post_options.map(Into::into), ) .await?; @@ -170,7 +172,10 @@ impl EventTypeCommands { } => { let resp = client .event_type() - .patch(event_type_name, event_type_patch.into_inner()) + .patch( + event_type_name, + event_type_patch.map(|x| x.into_inner()).unwrap_or_default(), + ) .await?; crate::json::print_json_output(&resp, color_mode)?; } diff --git a/svix-cli/src/json.rs b/svix-cli/src/json.rs index 0086a2dc3..533dd539f 100644 --- a/svix-cli/src/json.rs +++ b/svix-cli/src/json.rs @@ -4,8 +4,8 @@ use anyhow::{Error, Result}; use colored_json::{Color, ColorMode, ToColoredJson}; use serde::{de::DeserializeOwned, Serialize}; -#[derive(Clone, Debug, PartialEq)] -pub struct JsonOf(T); +#[derive(Clone, Debug, Default, PartialEq)] +pub struct JsonOf(T); impl FromStr for JsonOf { type Err = Error; @@ -15,7 +15,7 @@ impl FromStr for JsonOf { } } -impl JsonOf { +impl JsonOf { pub fn into_inner(self) -> T { self.0 }