mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-23 19:15:00 +01:00
2120 lines
65 KiB
Rust
2120 lines
65 KiB
Rust
use crate::error::Result;
|
|
use crate::models::HttpRequestIden::{
|
|
Authentication, AuthenticationType, Body, BodyType, CreatedAt, Description, FolderId, Headers,
|
|
Method, Name, SortPriority, UpdatedAt, Url, UrlParameters, WorkspaceId,
|
|
};
|
|
use crate::util::{UpdateSource, generate_prefixed_id};
|
|
use chrono::{NaiveDateTime, Utc};
|
|
use rusqlite::Row;
|
|
use sea_query::Order::Desc;
|
|
use sea_query::{IntoColumnRef, IntoIden, IntoTableRef, Order, SimpleExpr, enum_def};
|
|
use serde::{Deserialize, Deserializer, Serialize};
|
|
use serde_json::Value;
|
|
use std::collections::BTreeMap;
|
|
use std::fmt::Display;
|
|
use std::str::FromStr;
|
|
use ts_rs::TS;
|
|
|
|
#[macro_export]
|
|
macro_rules! impl_model {
|
|
($t:ty, $variant:ident) => {
|
|
impl $crate::Model for $t {
|
|
fn into_any(self) -> $crate::AnyModel {
|
|
$crate::AnyModel::$variant(self)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "camelCase", tag = "type")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum ProxySetting {
|
|
Enabled {
|
|
#[serde(default)]
|
|
// This was added after on so give it a default to be able to deserialize older values
|
|
disabled: bool,
|
|
http: String,
|
|
https: String,
|
|
auth: Option<ProxySettingAuth>,
|
|
},
|
|
Disabled,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct ProxySettingAuth {
|
|
pub user: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum EditorKeymap {
|
|
Default,
|
|
Vim,
|
|
Vscode,
|
|
Emacs,
|
|
}
|
|
|
|
impl FromStr for EditorKeymap {
|
|
type Err = crate::error::Error;
|
|
|
|
fn from_str(s: &str) -> Result<Self> {
|
|
match s {
|
|
"default" => Ok(Self::Default),
|
|
"vscode" => Ok(Self::Vscode),
|
|
"vim" => Ok(Self::Vim),
|
|
"emacs" => Ok(Self::Emacs),
|
|
_ => Ok(Self::default()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for EditorKeymap {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let str = match self {
|
|
EditorKeymap::Default => "default".to_string(),
|
|
EditorKeymap::Vscode => "vscode".to_string(),
|
|
EditorKeymap::Vim => "vim".to_string(),
|
|
EditorKeymap::Emacs => "emacs".to_string(),
|
|
};
|
|
write!(f, "{}", str)
|
|
}
|
|
}
|
|
|
|
impl Default for EditorKeymap {
|
|
fn default() -> Self {
|
|
Self::Default
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "settings")]
|
|
pub struct Settings {
|
|
#[ts(type = "\"settings\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
pub appearance: String,
|
|
pub editor_font_size: i32,
|
|
pub editor_soft_wrap: bool,
|
|
pub hide_window_controls: bool,
|
|
pub interface_font_size: i32,
|
|
pub interface_scale: f32,
|
|
pub open_workspace_new_window: Option<bool>,
|
|
pub proxy: Option<ProxySetting>,
|
|
pub theme_dark: String,
|
|
pub theme_light: String,
|
|
pub update_channel: String,
|
|
pub editor_keymap: EditorKeymap,
|
|
}
|
|
|
|
impl UpsertModelInfo for Settings {
|
|
fn table_name() -> impl IntoTableRef {
|
|
SettingsIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
SettingsIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
panic!("Settings does not have unique IDs")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(SettingsIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use SettingsIden::*;
|
|
let proxy = match self.proxy {
|
|
None => None,
|
|
Some(p) => Some(serde_json::to_string(&p)?),
|
|
};
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(Appearance, self.appearance.as_str().into()),
|
|
(EditorFontSize, self.editor_font_size.into()),
|
|
(EditorKeymap, self.editor_keymap.to_string().into()),
|
|
(EditorSoftWrap, self.editor_soft_wrap.into()),
|
|
(InterfaceFontSize, self.interface_font_size.into()),
|
|
(InterfaceScale, self.interface_scale.into()),
|
|
(HideWindowControls, self.hide_window_controls.into()),
|
|
(OpenWorkspaceNewWindow, self.open_workspace_new_window.into()),
|
|
(ThemeDark, self.theme_dark.as_str().into()),
|
|
(ThemeLight, self.theme_light.as_str().into()),
|
|
(UpdateChannel, self.update_channel.into()),
|
|
(Proxy, proxy.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
SettingsIden::UpdatedAt,
|
|
SettingsIden::Appearance,
|
|
SettingsIden::EditorFontSize,
|
|
SettingsIden::EditorKeymap,
|
|
SettingsIden::EditorSoftWrap,
|
|
SettingsIden::InterfaceFontSize,
|
|
SettingsIden::InterfaceScale,
|
|
SettingsIden::HideWindowControls,
|
|
SettingsIden::OpenWorkspaceNewWindow,
|
|
SettingsIden::Proxy,
|
|
SettingsIden::ThemeDark,
|
|
SettingsIden::ThemeLight,
|
|
SettingsIden::UpdateChannel,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let proxy: Option<String> = row.get("proxy")?;
|
|
let editor_keymap: String = row.get("editor_keymap")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
appearance: row.get("appearance")?,
|
|
editor_font_size: row.get("editor_font_size")?,
|
|
editor_keymap: EditorKeymap::from_str(editor_keymap.as_str()).unwrap(),
|
|
editor_soft_wrap: row.get("editor_soft_wrap")?,
|
|
interface_font_size: row.get("interface_font_size")?,
|
|
interface_scale: row.get("interface_scale")?,
|
|
open_workspace_new_window: row.get("open_workspace_new_window")?,
|
|
proxy: proxy.map(|p| -> ProxySetting { serde_json::from_str(p.as_str()).unwrap() }),
|
|
theme_dark: row.get("theme_dark")?,
|
|
theme_light: row.get("theme_light")?,
|
|
hide_window_controls: row.get("hide_window_controls")?,
|
|
update_channel: row.get("update_channel")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "workspaces")]
|
|
pub struct Workspace {
|
|
#[ts(type = "\"workspace\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub authentication_type: Option<String>,
|
|
pub description: String,
|
|
pub headers: Vec<HttpRequestHeader>,
|
|
pub name: String,
|
|
pub encryption_key_challenge: Option<String>,
|
|
|
|
// Settings
|
|
#[serde(default = "default_true")]
|
|
pub setting_validate_certificates: bool,
|
|
#[serde(default = "default_true")]
|
|
pub setting_follow_redirects: bool,
|
|
pub setting_request_timeout: i32,
|
|
}
|
|
|
|
impl UpsertModelInfo for Workspace {
|
|
fn table_name() -> impl IntoTableRef {
|
|
WorkspaceIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
WorkspaceIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("wk")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(WorkspaceIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use WorkspaceIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(Name, self.name.trim().into()),
|
|
(Authentication, serde_json::to_string(&self.authentication)?.into()),
|
|
(AuthenticationType, self.authentication_type.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(Description, self.description.into()),
|
|
(EncryptionKeyChallenge, self.encryption_key_challenge.into()),
|
|
(SettingFollowRedirects, self.setting_follow_redirects.into()),
|
|
(SettingRequestTimeout, self.setting_request_timeout.into()),
|
|
(SettingValidateCertificates, self.setting_validate_certificates.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
WorkspaceIden::UpdatedAt,
|
|
WorkspaceIden::Name,
|
|
WorkspaceIden::Authentication,
|
|
WorkspaceIden::AuthenticationType,
|
|
WorkspaceIden::Headers,
|
|
WorkspaceIden::Description,
|
|
WorkspaceIden::EncryptionKeyChallenge,
|
|
WorkspaceIden::SettingRequestTimeout,
|
|
WorkspaceIden::SettingFollowRedirects,
|
|
WorkspaceIden::SettingRequestTimeout,
|
|
WorkspaceIden::SettingValidateCertificates,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let headers: String = row.get("headers")?;
|
|
let authentication: String = row.get("authentication")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
name: row.get("name")?,
|
|
description: row.get("description")?,
|
|
encryption_key_challenge: row.get("encryption_key_challenge")?,
|
|
headers: serde_json::from_str(&headers).unwrap_or_default(),
|
|
authentication: serde_json::from_str(&authentication).unwrap_or_default(),
|
|
authentication_type: row.get("authentication_type")?,
|
|
setting_follow_redirects: row.get("setting_follow_redirects")?,
|
|
setting_request_timeout: row.get("setting_request_timeout")?,
|
|
setting_validate_certificates: row.get("setting_validate_certificates")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct EncryptedKey {
|
|
pub encrypted_key: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "workspace_metas")]
|
|
pub struct WorkspaceMeta {
|
|
#[ts(type = "\"workspace_meta\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub workspace_id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub encryption_key: Option<EncryptedKey>,
|
|
pub setting_sync_dir: Option<String>,
|
|
}
|
|
|
|
impl UpsertModelInfo for WorkspaceMeta {
|
|
fn table_name() -> impl IntoTableRef {
|
|
WorkspaceMetaIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
WorkspaceMetaIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("wm")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(WorkspaceMetaIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use WorkspaceMetaIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(EncryptionKey, self.encryption_key.map(|e| serde_json::to_string(&e).unwrap()).into()),
|
|
(SettingSyncDir, self.setting_sync_dir.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
WorkspaceMetaIden::UpdatedAt,
|
|
WorkspaceMetaIden::EncryptionKey,
|
|
WorkspaceMetaIden::SettingSyncDir,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let encryption_key: Option<String> = row.get("encryption_key")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
encryption_key: encryption_key.map(|e| serde_json::from_str(&e).unwrap()),
|
|
setting_sync_dir: row.get("setting_sync_dir")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum CookieDomain {
|
|
HostOnly(String),
|
|
Suffix(String),
|
|
NotPresent,
|
|
Empty,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum CookieExpires {
|
|
AtUtc(String),
|
|
SessionEnd,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct Cookie {
|
|
pub raw_cookie: String,
|
|
pub domain: CookieDomain,
|
|
pub expires: CookieExpires,
|
|
pub path: (String, bool),
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "cookie_jars")]
|
|
pub struct CookieJar {
|
|
#[ts(type = "\"cookie_jar\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
|
|
pub cookies: Vec<Cookie>,
|
|
pub name: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for CookieJar {
|
|
fn table_name() -> impl IntoTableRef {
|
|
CookieJarIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
CookieJarIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("cj")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(CookieJarIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use CookieJarIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(Name, self.name.trim().into()),
|
|
(Cookies, serde_json::to_string(&self.cookies)?.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
CookieJarIden::UpdatedAt,
|
|
CookieJarIden::Name,
|
|
CookieJarIden::Cookies,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let cookies: String = row.get("cookies")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
name: row.get("name")?,
|
|
cookies: serde_json::from_str(cookies.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "environments")]
|
|
pub struct Environment {
|
|
#[ts(type = "\"environment\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub workspace_id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
pub name: String,
|
|
pub public: bool,
|
|
pub base: bool,
|
|
pub variables: Vec<EnvironmentVariable>,
|
|
}
|
|
|
|
impl UpsertModelInfo for Environment {
|
|
fn table_name() -> impl IntoTableRef {
|
|
EnvironmentIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
EnvironmentIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("ev")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(EnvironmentIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use EnvironmentIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(Base, self.base.into()),
|
|
(Name, self.name.trim().into()),
|
|
(Public, self.public.into()),
|
|
(Variables, serde_json::to_string(&self.variables)?.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
EnvironmentIden::UpdatedAt,
|
|
EnvironmentIden::Base,
|
|
EnvironmentIden::Name,
|
|
EnvironmentIden::Public,
|
|
EnvironmentIden::Variables,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let variables: String = row.get("variables")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
base: row.get("base")?,
|
|
name: row.get("name")?,
|
|
public: row.get("public")?,
|
|
variables: serde_json::from_str(variables.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct EnvironmentVariable {
|
|
#[serde(default = "default_true")]
|
|
#[ts(optional, as = "Option<bool>")]
|
|
pub enabled: bool,
|
|
pub name: String,
|
|
pub value: String,
|
|
#[ts(optional, as = "Option<String>")]
|
|
pub id: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct ParentAuthentication {
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub authentication_type: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct ParentHeaders {
|
|
pub headers: Vec<HttpRequestHeader>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "folders")]
|
|
pub struct Folder {
|
|
#[ts(type = "\"folder\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub folder_id: Option<String>,
|
|
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub authentication_type: Option<String>,
|
|
pub description: String,
|
|
pub headers: Vec<HttpRequestHeader>,
|
|
pub name: String,
|
|
pub sort_priority: f32,
|
|
}
|
|
|
|
impl UpsertModelInfo for Folder {
|
|
fn table_name() -> impl IntoTableRef {
|
|
FolderIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
FolderIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("fl")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(FolderIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use FolderIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(FolderId, self.folder_id.into()),
|
|
(Authentication, serde_json::to_string(&self.authentication)?.into()),
|
|
(AuthenticationType, self.authentication_type.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(Description, self.description.into()),
|
|
(Name, self.name.trim().into()),
|
|
(SortPriority, self.sort_priority.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
FolderIden::UpdatedAt,
|
|
FolderIden::Name,
|
|
FolderIden::Authentication,
|
|
FolderIden::AuthenticationType,
|
|
FolderIden::Headers,
|
|
FolderIden::Description,
|
|
FolderIden::FolderId,
|
|
FolderIden::SortPriority,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let headers: String = row.get("headers")?;
|
|
let authentication: String = row.get("authentication")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
sort_priority: row.get("sort_priority")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
folder_id: row.get("folder_id")?,
|
|
name: row.get("name")?,
|
|
description: row.get("description")?,
|
|
headers: serde_json::from_str(&headers).unwrap_or_default(),
|
|
authentication_type: row.get("authentication_type")?,
|
|
authentication: serde_json::from_str(&authentication).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct HttpRequestHeader {
|
|
#[serde(default = "default_true")]
|
|
#[ts(optional, as = "Option<bool>")]
|
|
pub enabled: bool,
|
|
pub name: String,
|
|
pub value: String,
|
|
#[ts(optional, as = "Option<String>")]
|
|
pub id: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct HttpUrlParameter {
|
|
#[serde(default = "default_true")]
|
|
#[ts(optional, as = "Option<bool>")]
|
|
pub enabled: bool,
|
|
pub name: String,
|
|
pub value: String,
|
|
#[ts(optional, as = "Option<String>")]
|
|
pub id: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "http_requests")]
|
|
pub struct HttpRequest {
|
|
#[ts(type = "\"http_request\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub folder_id: Option<String>,
|
|
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub authentication_type: Option<String>,
|
|
#[ts(type = "Record<string, any>")]
|
|
pub body: BTreeMap<String, Value>,
|
|
pub body_type: Option<String>,
|
|
pub description: String,
|
|
pub headers: Vec<HttpRequestHeader>,
|
|
#[serde(default = "default_http_method")]
|
|
pub method: String,
|
|
pub name: String,
|
|
pub sort_priority: f64,
|
|
pub url: String,
|
|
pub url_parameters: Vec<HttpUrlParameter>,
|
|
}
|
|
|
|
impl UpsertModelInfo for HttpRequest {
|
|
fn table_name() -> impl IntoTableRef {
|
|
HttpRequestIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
HttpRequestIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("rq")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(HttpResponseIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.to_string()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(FolderId, self.folder_id.into()),
|
|
(Name, self.name.trim().into()),
|
|
(Description, self.description.into()),
|
|
(Url, self.url.into()),
|
|
(UrlParameters, serde_json::to_string(&self.url_parameters)?.into()),
|
|
(Method, self.method.into()),
|
|
(Body, serde_json::to_string(&self.body)?.into()),
|
|
(BodyType, self.body_type.into()),
|
|
(Authentication, serde_json::to_string(&self.authentication)?.into()),
|
|
(AuthenticationType, self.authentication_type.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(SortPriority, self.sort_priority.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
UpdatedAt,
|
|
WorkspaceId,
|
|
Name,
|
|
Description,
|
|
FolderId,
|
|
Method,
|
|
Headers,
|
|
Body,
|
|
BodyType,
|
|
Authentication,
|
|
AuthenticationType,
|
|
Url,
|
|
UrlParameters,
|
|
SortPriority,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self> {
|
|
let url_parameters: String = row.get("url_parameters")?;
|
|
let body: String = row.get("body")?;
|
|
let authentication: String = row.get("authentication")?;
|
|
let headers: String = row.get("headers")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
|
|
authentication_type: row.get("authentication_type")?,
|
|
body: serde_json::from_str(body.as_str()).unwrap_or_default(),
|
|
body_type: row.get("body_type")?,
|
|
description: row.get("description")?,
|
|
folder_id: row.get("folder_id")?,
|
|
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
|
|
method: row.get("method")?,
|
|
name: row.get("name")?,
|
|
sort_priority: row.get("sort_priority")?,
|
|
url: row.get("url")?,
|
|
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum WebsocketConnectionState {
|
|
Initialized,
|
|
Connected,
|
|
Closing,
|
|
Closed,
|
|
}
|
|
|
|
impl Default for WebsocketConnectionState {
|
|
fn default() -> Self {
|
|
Self::Initialized
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "websocket_connections")]
|
|
pub struct WebsocketConnection {
|
|
#[ts(type = "\"websocket_connection\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub request_id: String,
|
|
|
|
pub elapsed: i32,
|
|
pub error: Option<String>,
|
|
pub headers: Vec<HttpResponseHeader>,
|
|
pub state: WebsocketConnectionState,
|
|
pub status: i32,
|
|
pub url: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for WebsocketConnection {
|
|
fn table_name() -> impl IntoTableRef {
|
|
WebsocketConnectionIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
WebsocketConnectionIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("wc")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(WebsocketConnectionIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use WebsocketConnectionIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(RequestId, self.request_id.into()),
|
|
(Elapsed, self.elapsed.into()),
|
|
(Error, self.error.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(State, serde_json::to_value(&self.state)?.as_str().into()),
|
|
(Status, self.status.into()),
|
|
(Url, self.url.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
WebsocketConnectionIden::UpdatedAt,
|
|
WebsocketConnectionIden::Elapsed,
|
|
WebsocketConnectionIden::Error,
|
|
WebsocketConnectionIden::Headers,
|
|
WebsocketConnectionIden::State,
|
|
WebsocketConnectionIden::Status,
|
|
WebsocketConnectionIden::Url,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let headers: String = row.get("headers")?;
|
|
let state: String = row.get("state")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
request_id: row.get("request_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
url: row.get("url")?,
|
|
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
|
|
elapsed: row.get("elapsed")?,
|
|
error: row.get("error")?,
|
|
state: serde_json::from_str(format!(r#""{state}""#).as_str()).unwrap(),
|
|
status: row.get("status")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum WebsocketMessageType {
|
|
Text,
|
|
Binary,
|
|
}
|
|
|
|
impl Default for WebsocketMessageType {
|
|
fn default() -> Self {
|
|
Self::Text
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "websocket_requests")]
|
|
pub struct WebsocketRequest {
|
|
#[ts(type = "\"websocket_request\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub folder_id: Option<String>,
|
|
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub authentication_type: Option<String>,
|
|
pub description: String,
|
|
pub headers: Vec<HttpRequestHeader>,
|
|
pub message: String,
|
|
pub name: String,
|
|
pub sort_priority: f32,
|
|
pub url: String,
|
|
pub url_parameters: Vec<HttpUrlParameter>,
|
|
}
|
|
|
|
impl UpsertModelInfo for WebsocketRequest {
|
|
fn table_name() -> impl IntoTableRef {
|
|
WebsocketRequestIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
WebsocketRequestIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("wr")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(WebsocketRequestIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use WebsocketRequestIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(FolderId, self.folder_id.as_ref().map(|s| s.as_str()).into()),
|
|
(Authentication, serde_json::to_string(&self.authentication)?.into()),
|
|
(AuthenticationType, self.authentication_type.into()),
|
|
(Description, self.description.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(Message, self.message.into()),
|
|
(Name, self.name.trim().into()),
|
|
(SortPriority, self.sort_priority.into()),
|
|
(Url, self.url.into()),
|
|
(UrlParameters, serde_json::to_string(&self.url_parameters)?.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
WebsocketRequestIden::UpdatedAt,
|
|
WebsocketRequestIden::WorkspaceId,
|
|
WebsocketRequestIden::FolderId,
|
|
WebsocketRequestIden::Authentication,
|
|
WebsocketRequestIden::AuthenticationType,
|
|
WebsocketRequestIden::Description,
|
|
WebsocketRequestIden::Headers,
|
|
WebsocketRequestIden::Message,
|
|
WebsocketRequestIden::Name,
|
|
WebsocketRequestIden::SortPriority,
|
|
WebsocketRequestIden::Url,
|
|
WebsocketRequestIden::UrlParameters,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let url_parameters: String = row.get("url_parameters")?;
|
|
let authentication: String = row.get("authentication")?;
|
|
let headers: String = row.get("headers")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
sort_priority: row.get("sort_priority")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
url: row.get("url")?,
|
|
url_parameters: serde_json::from_str(url_parameters.as_str()).unwrap_or_default(),
|
|
message: row.get("message")?,
|
|
description: row.get("description")?,
|
|
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
|
|
authentication_type: row.get("authentication_type")?,
|
|
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
|
|
folder_id: row.get("folder_id")?,
|
|
name: row.get("name")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum WebsocketEventType {
|
|
Binary,
|
|
Close,
|
|
Frame,
|
|
Open,
|
|
Ping,
|
|
Pong,
|
|
Text,
|
|
}
|
|
|
|
impl Default for WebsocketEventType {
|
|
fn default() -> Self {
|
|
Self::Text
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "websocket_events")]
|
|
pub struct WebsocketEvent {
|
|
#[ts(type = "\"websocket_event\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub request_id: String,
|
|
pub connection_id: String,
|
|
pub is_server: bool,
|
|
|
|
pub message: Vec<u8>,
|
|
pub message_type: WebsocketEventType,
|
|
}
|
|
|
|
impl UpsertModelInfo for WebsocketEvent {
|
|
fn table_name() -> impl IntoTableRef {
|
|
WebsocketEventIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
WebsocketEventIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("we")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(WebsocketEventIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use WebsocketEventIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(ConnectionId, self.connection_id.into()),
|
|
(RequestId, self.request_id.into()),
|
|
(MessageType, serde_json::to_string(&self.message_type)?.into()),
|
|
(IsServer, self.is_server.into()),
|
|
(Message, self.message.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
WebsocketEventIden::UpdatedAt,
|
|
WebsocketEventIden::MessageType,
|
|
WebsocketEventIden::IsServer,
|
|
WebsocketEventIden::Message,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let message_type: String = row.get("message_type")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
request_id: row.get("request_id")?,
|
|
connection_id: row.get("connection_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
message: row.get("message")?,
|
|
is_server: row.get("is_server")?,
|
|
message_type: serde_json::from_str(message_type.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub struct HttpResponseHeader {
|
|
pub name: String,
|
|
pub value: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum HttpResponseState {
|
|
Initialized,
|
|
Connected,
|
|
Closed,
|
|
}
|
|
|
|
impl Default for HttpResponseState {
|
|
fn default() -> Self {
|
|
Self::Initialized
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "http_responses")]
|
|
pub struct HttpResponse {
|
|
#[ts(type = "\"http_response\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub request_id: String,
|
|
|
|
pub body_path: Option<String>,
|
|
pub content_length: Option<i32>,
|
|
pub elapsed: i32,
|
|
pub elapsed_headers: i32,
|
|
pub error: Option<String>,
|
|
pub headers: Vec<HttpResponseHeader>,
|
|
pub remote_addr: Option<String>,
|
|
pub status: i32,
|
|
pub status_reason: Option<String>,
|
|
pub state: HttpResponseState,
|
|
pub url: String,
|
|
pub version: Option<String>,
|
|
}
|
|
|
|
impl UpsertModelInfo for HttpResponse {
|
|
fn table_name() -> impl IntoTableRef {
|
|
HttpResponseIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
HttpResponseIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("rs")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(HttpResponseIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use HttpResponseIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(RequestId, self.request_id.into()),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(BodyPath, self.body_path.into()),
|
|
(ContentLength, self.content_length.into()),
|
|
(Elapsed, self.elapsed.into()),
|
|
(ElapsedHeaders, self.elapsed_headers.into()),
|
|
(Error, self.error.into()),
|
|
(Headers, serde_json::to_string(&self.headers)?.into()),
|
|
(RemoteAddr, self.remote_addr.into()),
|
|
(State, serde_json::to_value(self.state)?.as_str().into()),
|
|
(Status, self.status.into()),
|
|
(StatusReason, self.status_reason.into()),
|
|
(Url, self.url.into()),
|
|
(Version, self.version.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
HttpResponseIden::UpdatedAt,
|
|
HttpResponseIden::BodyPath,
|
|
HttpResponseIden::ContentLength,
|
|
HttpResponseIden::Elapsed,
|
|
HttpResponseIden::ElapsedHeaders,
|
|
HttpResponseIden::Error,
|
|
HttpResponseIden::Headers,
|
|
HttpResponseIden::RemoteAddr,
|
|
HttpResponseIden::State,
|
|
HttpResponseIden::Status,
|
|
HttpResponseIden::StatusReason,
|
|
HttpResponseIden::Url,
|
|
HttpResponseIden::Version,
|
|
]
|
|
}
|
|
|
|
fn from_row(r: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let headers: String = r.get("headers")?;
|
|
let state: String = r.get("state")?;
|
|
Ok(Self {
|
|
id: r.get("id")?,
|
|
model: r.get("model")?,
|
|
workspace_id: r.get("workspace_id")?,
|
|
request_id: r.get("request_id")?,
|
|
created_at: r.get("created_at")?,
|
|
updated_at: r.get("updated_at")?,
|
|
error: r.get("error")?,
|
|
url: r.get("url")?,
|
|
content_length: r.get("content_length")?,
|
|
version: r.get("version")?,
|
|
elapsed: r.get("elapsed")?,
|
|
elapsed_headers: r.get("elapsed_headers")?,
|
|
remote_addr: r.get("remote_addr")?,
|
|
status: r.get("status")?,
|
|
status_reason: r.get("status_reason")?,
|
|
state: serde_json::from_str(format!(r#""{state}""#).as_str()).unwrap(),
|
|
body_path: r.get("body_path")?,
|
|
headers: serde_json::from_str(headers.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "grpc_requests")]
|
|
pub struct GrpcRequest {
|
|
#[ts(type = "\"grpc_request\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub folder_id: Option<String>,
|
|
|
|
pub authentication_type: Option<String>,
|
|
#[ts(type = "Record<string, any>")]
|
|
pub authentication: BTreeMap<String, Value>,
|
|
pub description: String,
|
|
pub message: String,
|
|
pub metadata: Vec<HttpRequestHeader>,
|
|
pub method: Option<String>,
|
|
pub name: String,
|
|
pub service: Option<String>,
|
|
pub sort_priority: f32,
|
|
pub url: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for GrpcRequest {
|
|
fn table_name() -> impl IntoTableRef {
|
|
GrpcRequestIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
GrpcRequestIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("gr")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(GrpcRequestIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use GrpcRequestIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(Name, self.name.trim().into()),
|
|
(Description, self.description.into()),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(FolderId, self.folder_id.into()),
|
|
(SortPriority, self.sort_priority.into()),
|
|
(Url, self.url.into()),
|
|
(Service, self.service.into()),
|
|
(Method, self.method.into()),
|
|
(Message, self.message.into()),
|
|
(AuthenticationType, self.authentication_type.into()),
|
|
(Authentication, serde_json::to_string(&self.authentication)?.into()),
|
|
(Metadata, serde_json::to_string(&self.metadata)?.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
GrpcRequestIden::UpdatedAt,
|
|
GrpcRequestIden::WorkspaceId,
|
|
GrpcRequestIden::Name,
|
|
GrpcRequestIden::Description,
|
|
GrpcRequestIden::FolderId,
|
|
GrpcRequestIden::SortPriority,
|
|
GrpcRequestIden::Url,
|
|
GrpcRequestIden::Service,
|
|
GrpcRequestIden::Method,
|
|
GrpcRequestIden::Message,
|
|
GrpcRequestIden::AuthenticationType,
|
|
GrpcRequestIden::Authentication,
|
|
GrpcRequestIden::Metadata,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let authentication: String = row.get("authentication")?;
|
|
let metadata: String = row.get("metadata")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
folder_id: row.get("folder_id")?,
|
|
name: row.get("name")?,
|
|
description: row.get("description")?,
|
|
service: row.get("service")?,
|
|
method: row.get("method")?,
|
|
message: row.get("message")?,
|
|
authentication_type: row.get("authentication_type")?,
|
|
authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(),
|
|
url: row.get("url")?,
|
|
sort_priority: row.get("sort_priority")?,
|
|
metadata: serde_json::from_str(metadata.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum GrpcConnectionState {
|
|
Initialized,
|
|
Connected,
|
|
Closed,
|
|
}
|
|
|
|
impl Default for GrpcConnectionState {
|
|
fn default() -> Self {
|
|
Self::Initialized
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "grpc_connections")]
|
|
pub struct GrpcConnection {
|
|
#[ts(type = "\"grpc_connection\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub request_id: String,
|
|
|
|
pub elapsed: i32,
|
|
pub error: Option<String>,
|
|
pub method: String,
|
|
pub service: String,
|
|
pub status: i32,
|
|
pub state: GrpcConnectionState,
|
|
pub trailers: BTreeMap<String, String>,
|
|
pub url: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for GrpcConnection {
|
|
fn table_name() -> impl IntoTableRef {
|
|
GrpcConnectionIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
GrpcConnectionIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("gc")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(GrpcConnectionIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use GrpcConnectionIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(RequestId, self.request_id.into()),
|
|
(Service, self.service.into()),
|
|
(Method, self.method.into()),
|
|
(Elapsed, self.elapsed.into()),
|
|
(State, serde_json::to_value(&self.state)?.as_str().into()),
|
|
(Status, self.status.into()),
|
|
(Error, self.error.as_ref().map(|s| s.as_str()).into()),
|
|
(Trailers, serde_json::to_string(&self.trailers)?.into()),
|
|
(Url, self.url.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
GrpcConnectionIden::UpdatedAt,
|
|
GrpcConnectionIden::Service,
|
|
GrpcConnectionIden::Method,
|
|
GrpcConnectionIden::Elapsed,
|
|
GrpcConnectionIden::Status,
|
|
GrpcConnectionIden::State,
|
|
GrpcConnectionIden::Error,
|
|
GrpcConnectionIden::Trailers,
|
|
GrpcConnectionIden::Url,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let trailers: String = row.get("trailers")?;
|
|
let state: String = row.get("state")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
request_id: row.get("request_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
service: row.get("service")?,
|
|
method: row.get("method")?,
|
|
elapsed: row.get("elapsed")?,
|
|
state: serde_json::from_str(format!(r#""{state}""#).as_str()).unwrap(),
|
|
status: row.get("status")?,
|
|
url: row.get("url")?,
|
|
error: row.get("error")?,
|
|
trailers: serde_json::from_str(trailers.as_str()).unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum GrpcEventType {
|
|
Info,
|
|
Error,
|
|
ClientMessage,
|
|
ServerMessage,
|
|
ConnectionStart,
|
|
ConnectionEnd,
|
|
}
|
|
|
|
impl Default for GrpcEventType {
|
|
fn default() -> Self {
|
|
GrpcEventType::Info
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "grpc_events")]
|
|
pub struct GrpcEvent {
|
|
#[ts(type = "\"grpc_event\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub workspace_id: String,
|
|
pub request_id: String,
|
|
pub connection_id: String,
|
|
|
|
pub content: String,
|
|
pub error: Option<String>,
|
|
pub event_type: GrpcEventType,
|
|
pub metadata: BTreeMap<String, String>,
|
|
pub status: Option<i32>,
|
|
}
|
|
|
|
impl UpsertModelInfo for GrpcEvent {
|
|
fn table_name() -> impl IntoTableRef {
|
|
GrpcEventIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
GrpcEventIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("ge")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(GrpcEventIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use GrpcEventIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(RequestId, self.request_id.into()),
|
|
(ConnectionId, self.connection_id.into()),
|
|
(Content, self.content.into()),
|
|
(EventType, serde_json::to_string(&self.event_type)?.into()),
|
|
(Metadata, serde_json::to_string(&self.metadata)?.into()),
|
|
(Status, self.status.into()),
|
|
(Error, self.error.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
GrpcEventIden::UpdatedAt,
|
|
GrpcEventIden::Content,
|
|
GrpcEventIden::EventType,
|
|
GrpcEventIden::Metadata,
|
|
GrpcEventIden::Status,
|
|
GrpcEventIden::Error,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let event_type: String = row.get("event_type")?;
|
|
let metadata: String = row.get("metadata")?;
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
request_id: row.get("request_id")?,
|
|
connection_id: row.get("connection_id")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
content: row.get("content")?,
|
|
event_type: serde_json::from_str(event_type.as_str()).unwrap_or_default(),
|
|
metadata: serde_json::from_str(metadata.as_str()).unwrap_or_default(),
|
|
status: row.get("status")?,
|
|
error: row.get("error")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "plugins")]
|
|
pub struct Plugin {
|
|
#[ts(type = "\"plugin\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
pub checked_at: Option<NaiveDateTime>,
|
|
pub directory: String,
|
|
pub enabled: bool,
|
|
pub url: Option<String>,
|
|
}
|
|
|
|
impl UpsertModelInfo for Plugin {
|
|
fn table_name() -> impl IntoTableRef {
|
|
PluginIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
PluginIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("pg")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(PluginIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use PluginIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(CheckedAt, self.checked_at.into()),
|
|
(Directory, self.directory.into()),
|
|
(Url, self.url.into()),
|
|
(Enabled, self.enabled.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
PluginIden::UpdatedAt,
|
|
PluginIden::CheckedAt,
|
|
PluginIden::Directory,
|
|
PluginIden::Url,
|
|
PluginIden::Enabled,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
checked_at: row.get("checked_at")?,
|
|
url: row.get("url")?,
|
|
directory: row.get("directory")?,
|
|
enabled: row.get("enabled")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "sync_states")]
|
|
pub struct SyncState {
|
|
#[ts(type = "\"sync_state\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub workspace_id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
pub flushed_at: NaiveDateTime,
|
|
|
|
pub model_id: String,
|
|
pub checksum: String,
|
|
pub rel_path: String,
|
|
pub sync_dir: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for SyncState {
|
|
fn table_name() -> impl IntoTableRef {
|
|
SyncStateIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
SyncStateIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("ss")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(SyncStateIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use SyncStateIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(WorkspaceId, self.workspace_id.into()),
|
|
(FlushedAt, self.flushed_at.into()),
|
|
(Checksum, self.checksum.into()),
|
|
(ModelId, self.model_id.into()),
|
|
(RelPath, self.rel_path.into()),
|
|
(SyncDir, self.sync_dir.into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![
|
|
SyncStateIden::UpdatedAt,
|
|
SyncStateIden::FlushedAt,
|
|
SyncStateIden::Checksum,
|
|
SyncStateIden::RelPath,
|
|
SyncStateIden::SyncDir,
|
|
]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
workspace_id: row.get("workspace_id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
flushed_at: row.get("flushed_at")?,
|
|
checksum: row.get("checksum")?,
|
|
model_id: row.get("model_id")?,
|
|
sync_dir: row.get("sync_dir")?,
|
|
rel_path: row.get("rel_path")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "key_values")]
|
|
pub struct KeyValue {
|
|
#[ts(type = "\"key_value\"")]
|
|
pub model: String,
|
|
pub id: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
pub key: String,
|
|
pub namespace: String,
|
|
pub value: String,
|
|
}
|
|
|
|
impl UpsertModelInfo for KeyValue {
|
|
fn table_name() -> impl IntoTableRef {
|
|
KeyValueIden::Table
|
|
}
|
|
|
|
fn id_column() -> impl IntoIden + Eq + Clone {
|
|
KeyValueIden::Id
|
|
}
|
|
|
|
fn generate_id() -> String {
|
|
generate_prefixed_id("kv")
|
|
}
|
|
|
|
fn order_by() -> (impl IntoColumnRef, Order) {
|
|
(KeyValueIden::CreatedAt, Desc)
|
|
}
|
|
|
|
fn get_id(&self) -> String {
|
|
self.id.clone()
|
|
}
|
|
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>> {
|
|
use KeyValueIden::*;
|
|
Ok(vec![
|
|
(CreatedAt, upsert_date(source, self.created_at)),
|
|
(UpdatedAt, upsert_date(source, self.updated_at)),
|
|
(Namespace, self.namespace.clone().into()),
|
|
(Key, self.key.clone().into()),
|
|
(Value, self.value.clone().into()),
|
|
])
|
|
}
|
|
|
|
fn update_columns() -> Vec<impl IntoIden> {
|
|
vec![KeyValueIden::UpdatedAt, KeyValueIden::Value]
|
|
}
|
|
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
Ok(Self {
|
|
id: row.get("id")?,
|
|
model: row.get("model")?,
|
|
created_at: row.get("created_at")?,
|
|
updated_at: row.get("updated_at")?,
|
|
namespace: row.get("namespace")?,
|
|
key: row.get("key")?,
|
|
value: row.get("value")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
|
#[serde(default, rename_all = "camelCase")]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
#[enum_def(table_name = "plugin_key_values")]
|
|
pub struct PluginKeyValue {
|
|
#[ts(type = "\"plugin_key_value\"")]
|
|
pub model: String,
|
|
pub created_at: NaiveDateTime,
|
|
pub updated_at: NaiveDateTime,
|
|
|
|
pub plugin_name: String,
|
|
pub key: String,
|
|
pub value: String,
|
|
}
|
|
|
|
impl<'s> TryFrom<&Row<'s>> for PluginKeyValue {
|
|
type Error = rusqlite::Error;
|
|
|
|
fn try_from(r: &Row<'s>) -> std::result::Result<Self, Self::Error> {
|
|
Ok(Self {
|
|
model: r.get("model")?,
|
|
created_at: r.get("created_at")?,
|
|
updated_at: r.get("updated_at")?,
|
|
plugin_name: r.get("plugin_name")?,
|
|
key: r.get("key")?,
|
|
value: r.get("value")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
fn default_true() -> bool {
|
|
true
|
|
}
|
|
|
|
fn default_http_method() -> String {
|
|
"GET".to_string()
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! define_any_model {
|
|
($($type:ident),* $(,)?) => {
|
|
#[derive(Debug, Clone, Serialize, TS)]
|
|
#[serde(rename_all = "camelCase", untagged)]
|
|
#[ts(export, export_to = "gen_models.ts")]
|
|
pub enum AnyModel {
|
|
$(
|
|
$type($type),
|
|
)*
|
|
}
|
|
|
|
$(
|
|
impl From<$type> for AnyModel {
|
|
fn from(value: $type) -> Self {
|
|
AnyModel::$type(value)
|
|
}
|
|
}
|
|
|
|
impl From<AnyModel> for $type {
|
|
fn from(value: AnyModel) -> $type {
|
|
match value {
|
|
AnyModel::$type(inner) => inner,
|
|
_ => panic!( // Should never happen because this macro also generates the enum variant
|
|
"Tried to convert AnyModel into `{}`, but found a different variant",
|
|
stringify!($type)
|
|
),
|
|
}
|
|
}
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
|
|
define_any_model! {
|
|
CookieJar,
|
|
Environment,
|
|
Folder,
|
|
GrpcConnection,
|
|
GrpcEvent,
|
|
GrpcRequest,
|
|
HttpRequest,
|
|
HttpResponse,
|
|
KeyValue,
|
|
Plugin,
|
|
Settings,
|
|
SyncState,
|
|
WebsocketConnection,
|
|
WebsocketEvent,
|
|
WebsocketRequest,
|
|
Workspace,
|
|
WorkspaceMeta,
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for AnyModel {
|
|
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let value = Value::deserialize(deserializer)?;
|
|
let model = value.as_object().unwrap();
|
|
use serde_json::from_value as fv;
|
|
|
|
let model = match model.get("model") {
|
|
Some(m) if m == "cookie_jar" => AnyModel::CookieJar(fv(value).unwrap()),
|
|
Some(m) if m == "environment" => AnyModel::Environment(fv(value).unwrap()),
|
|
Some(m) if m == "folder" => AnyModel::Folder(fv(value).unwrap()),
|
|
Some(m) if m == "grpc_connection" => AnyModel::GrpcConnection(fv(value).unwrap()),
|
|
Some(m) if m == "grpc_event" => AnyModel::GrpcEvent(fv(value).unwrap()),
|
|
Some(m) if m == "grpc_request" => AnyModel::GrpcRequest(fv(value).unwrap()),
|
|
Some(m) if m == "http_request" => AnyModel::HttpRequest(fv(value).unwrap()),
|
|
Some(m) if m == "http_response" => AnyModel::HttpResponse(fv(value).unwrap()),
|
|
Some(m) if m == "key_value" => AnyModel::KeyValue(fv(value).unwrap()),
|
|
Some(m) if m == "plugin" => AnyModel::Plugin(fv(value).unwrap()),
|
|
Some(m) if m == "settings" => AnyModel::Settings(fv(value).unwrap()),
|
|
Some(m) if m == "websocket_connection" => {
|
|
AnyModel::WebsocketConnection(fv(value).unwrap())
|
|
}
|
|
Some(m) if m == "websocket_event" => AnyModel::WebsocketEvent(fv(value).unwrap()),
|
|
Some(m) if m == "websocket_request" => AnyModel::WebsocketRequest(fv(value).unwrap()),
|
|
Some(m) if m == "workspace" => AnyModel::Workspace(fv(value).unwrap()),
|
|
Some(m) if m == "workspace_meta" => AnyModel::WorkspaceMeta(fv(value).unwrap()),
|
|
Some(m) => {
|
|
return Err(serde::de::Error::custom(format!(
|
|
"Failed to deserialize AnyModel {}",
|
|
m
|
|
)));
|
|
}
|
|
None => {
|
|
return Err(serde::de::Error::custom("Missing or invalid model"));
|
|
}
|
|
};
|
|
|
|
Ok(model)
|
|
}
|
|
}
|
|
|
|
impl AnyModel {
|
|
pub fn resolved_name(&self) -> String {
|
|
let compute_name = |name: &str, url: &str, fallback: &str| -> String {
|
|
if !name.is_empty() {
|
|
return name.to_string();
|
|
}
|
|
let without_variables = url.replace(r"\$\{\[\s*([^\]\s]+)\s*]}", "$1");
|
|
if without_variables.is_empty() { fallback.to_string() } else { without_variables }
|
|
};
|
|
|
|
match self.clone() {
|
|
AnyModel::CookieJar(v) => v.name,
|
|
AnyModel::Environment(v) => v.name,
|
|
AnyModel::Folder(v) => v.name,
|
|
AnyModel::GrpcRequest(v) => compute_name(&v.name, &v.url, "gRPC Request"),
|
|
AnyModel::HttpRequest(v) => compute_name(&v.name, &v.url, "HTTP Request"),
|
|
AnyModel::WebsocketRequest(v) => compute_name(&v.name, &v.url, "WebSocket Request"),
|
|
AnyModel::Workspace(v) => v.name,
|
|
_ => "No Name".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait UpsertModelInfo {
|
|
fn table_name() -> impl IntoTableRef;
|
|
fn id_column() -> impl IntoIden + Eq + Clone;
|
|
fn generate_id() -> String;
|
|
fn order_by() -> (impl IntoColumnRef, Order);
|
|
fn get_id(&self) -> String;
|
|
fn insert_values(
|
|
self,
|
|
source: &UpdateSource,
|
|
) -> Result<Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>>;
|
|
fn update_columns() -> Vec<impl IntoIden>;
|
|
fn from_row(row: &Row) -> rusqlite::Result<Self>
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
// Generate the created_at or updated_at timestamps for an upsert operation, depending on the ID
|
|
// provided.
|
|
fn upsert_date(update_source: &UpdateSource, dt: NaiveDateTime) -> SimpleExpr {
|
|
match update_source {
|
|
// Sync and import operations always preserve timestamps
|
|
UpdateSource::Sync | UpdateSource::Import => {
|
|
if dt.and_utc().timestamp() == 0 {
|
|
// Sometimes data won't have timestamps (partial data)
|
|
Utc::now().naive_utc().into()
|
|
} else {
|
|
dt.into()
|
|
}
|
|
}
|
|
// Other sources will always update to the latest time
|
|
_ => Utc::now().naive_utc().into(),
|
|
}
|
|
}
|