1use crate::timestamps::Timestamp;
2use base64uuid::Base64Uuid;
3#[cfg(feature = "fp-bindgen")]
4use fp_bindgen::prelude::Serializable;
5use serde::{Deserialize, Serialize};
6use strum_macros::{Display, EnumIter};
7use typed_builder::TypedBuilder;
8
9#[allow(unused_imports)]
11use strum::IntoEnumIterator;
12
13#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize, Display, EnumIter)]
14#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
15#[cfg_attr(
16 feature = "fp-bindgen",
17 derive(Serializable),
18 fp(rust_module = "fiberplane_models::webhooks")
19)]
20#[non_exhaustive]
21#[serde(rename_all = "snake_case")]
22pub enum WebhookCategory {
23 Ping,
24 FrontMatter,
25}
26
27impl From<&WebhookCategory> for i16 {
28 fn from(value: &WebhookCategory) -> Self {
29 match value {
30 WebhookCategory::Ping => 0,
31 WebhookCategory::FrontMatter => 1,
32 }
33 }
34}
35
36impl From<WebhookCategory> for i16 {
37 fn from(value: WebhookCategory) -> Self {
38 (&value).into()
39 }
40}
41
42#[allow(clippy::from_over_into)]
45impl TryInto<WebhookCategory> for i16 {
46 type Error = InvalidWebhookCategoryError;
47
48 fn try_into(self) -> Result<WebhookCategory, Self::Error> {
49 match self {
50 0 => Ok(WebhookCategory::Ping),
51 1 => Ok(WebhookCategory::FrontMatter),
52 value => Err(InvalidWebhookCategoryError(value)),
53 }
54 }
55}
56
57#[derive(Debug, thiserror::Error, PartialEq, Eq)]
58#[cfg_attr(
59 feature = "fp-bindgen",
60 derive(Serializable),
61 fp(rust_module = "fiberplane_models::webhooks")
62)]
63#[error("unknown value {0}, expected 0 (ping) or 1 (front_matter)")]
64pub struct InvalidWebhookCategoryError(i16);
65
66#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
67#[cfg_attr(
68 feature = "fp-bindgen",
69 derive(Serializable),
70 fp(rust_module = "fiberplane_models::webhooks")
71)]
72#[non_exhaustive]
73#[serde(rename_all = "camelCase")]
74pub struct Webhook {
75 #[builder(setter(into))]
76 pub id: Base64Uuid,
77 #[builder(setter(into))]
78 pub workspace_id: Base64Uuid,
79
80 #[builder(setter(into))]
81 pub endpoint: String,
82 pub events: Vec<WebhookCategory>,
83 #[builder(default, setter(strip_option, into))]
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub shared_secret: Option<String>,
86 #[builder(default)]
87 pub enabled: bool,
88
89 #[builder(default)]
91 pub successful: bool,
92
93 #[builder(default, setter(strip_option, into))]
94 #[serde(default, skip_serializing_if = "Option::is_none")]
95 pub created_by: Option<Base64Uuid>,
96 #[builder(setter(into))]
97 pub created_at: Timestamp,
98 #[builder(setter(into))]
99 pub updated_at: Timestamp,
100}
101
102#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
103#[cfg_attr(
104 feature = "fp-bindgen",
105 derive(Serializable),
106 fp(rust_module = "fiberplane_models::webhooks")
107)]
108#[non_exhaustive]
109#[serde(rename_all = "camelCase")]
110pub struct NewWebhook {
111 #[builder(setter(into))]
112 pub endpoint: String,
113
114 pub events: Vec<WebhookCategory>,
115
116 #[builder(default)]
117 pub enabled: bool,
118}
119
120#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
121#[cfg_attr(
122 feature = "fp-bindgen",
123 derive(Serializable),
124 fp(rust_module = "fiberplane_models::webhooks")
125)]
126#[non_exhaustive]
127#[serde(rename_all = "camelCase")]
128pub struct UpdateWebhook {
129 #[builder(default, setter(strip_option, into))]
130 #[serde(default, skip_serializing_if = "Option::is_none")]
131 pub endpoint: Option<String>,
132
133 #[builder(default, setter(strip_option))]
134 #[serde(default, skip_serializing_if = "Option::is_none")]
135 pub events: Option<Vec<WebhookCategory>>,
136
137 #[builder(default)]
138 #[serde(default)]
139 pub regenerate_shared_secret: bool,
140
141 #[builder(default, setter(strip_option))]
142 #[serde(default, skip_serializing_if = "Option::is_none")]
143 pub enabled: Option<bool>,
144}
145
146#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
147#[cfg_attr(
148 feature = "fp-bindgen",
149 derive(Serializable),
150 fp(rust_module = "fiberplane_models::webhooks")
151)]
152#[non_exhaustive]
153#[serde(rename_all = "camelCase")]
154pub struct WebhookDelivery {
155 #[builder(setter(into))]
156 pub id: Base64Uuid,
157 #[builder(setter(into))]
158 pub webhook_id: Base64Uuid,
159 #[builder(setter(into))]
160 pub event: String,
161
162 #[builder(default, setter(strip_option))]
163 #[serde(default, skip_serializing_if = "Option::is_none")]
164 pub status_code: Option<i32>,
165 #[builder(default, setter(into, strip_option))]
166 #[serde(default, skip_serializing_if = "Option::is_none")]
167 pub status_text: Option<String>,
168
169 #[builder(default, setter(into))]
170 pub request_headers: String,
171 #[builder(default, setter(into))]
172 pub request_body: String,
173
174 #[builder(default, setter(into, strip_option))]
175 #[serde(default, skip_serializing_if = "Option::is_none")]
176 pub response_headers: Option<String>,
177 #[builder(default, setter(into, strip_option))]
178 #[serde(default, skip_serializing_if = "Option::is_none")]
179 pub response_body: Option<String>,
180
181 #[builder(setter(into))]
182 pub sent_request_at: Timestamp,
183 #[builder(default, setter(into, strip_option))]
184 #[serde(default, skip_serializing_if = "Option::is_none")]
185 pub received_response_at: Option<Timestamp>,
186}
187
188#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
189#[cfg_attr(
190 feature = "fp-bindgen",
191 derive(Serializable),
192 fp(rust_module = "fiberplane_models::webhooks")
193)]
194#[non_exhaustive]
195#[serde(rename_all = "camelCase")]
196pub struct WebhookDeliverySummary {
197 #[builder(setter(into))]
198 pub id: Base64Uuid,
199
200 #[builder(setter(into))]
201 pub event: String,
202
203 pub successful: bool,
204
205 #[builder(setter(into))]
206 pub timestamp: Timestamp,
207}