From 2a0211190aac828ee6efea82a1130dd4aaf206ed Mon Sep 17 00:00:00 2001
From: Flori <39242991+bitfl0wer@users.noreply.github.com>
Date: Thu, 25 May 2023 18:33:17 +0200
Subject: [PATCH 01/11] Update README.md
---
README.md | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 2865df4..1161e10 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,15 @@
-[![Rust]][Rust-url]
+[![Discord]][Discord-invite]
[![Build][build-shield]][build-url]
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
-[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
-[![GPL3 License][license-shield]][license-url]
-
+
Chorus
@@ -54,15 +52,17 @@ Core functionality:
[Rust]: https://img.shields.io/badge/Rust-orange?style=plastic&logo=rust
[Rust-url]: https://www.rust-lang.org/
-[build-shield]: https://img.shields.io/github/actions/workflow/status/polyphony-chat/chorus/rust.yml?style=plastic
+[build-shield]: https://img.shields.io/github/actions/workflow/status/polyphony-chat/chorus/rust.yml?style=flat
[build-url]: https://github.com/polyphony-chat/chorus/blob/main/.github/workflows/rust.yml
-[contributors-shield]: https://img.shields.io/github/contributors/polyphony-chat/chorus.svg?style=plastic
+[contributors-shield]: https://img.shields.io/github/contributors/polyphony-chat/chorus.svg?style=flat
[contributors-url]: https://github.com/polyphony-chat/chorus/graphs/contributors
-[forks-shield]: https://img.shields.io/github/forks/polyphony-chat/chorus.svg?style=plastic
+[forks-shield]: https://img.shields.io/github/forks/polyphony-chat/chorus.svg?style=flat
[forks-url]: https://github.com/polyphony-chat/chorus/network/members
-[stars-shield]: https://img.shields.io/github/stars/polyphony-chat/chorus.svg?style=plastic
+[stars-shield]: https://img.shields.io/github/stars/polyphony-chat/chorus.svg?style=flat
[stars-url]: https://github.com/polyphony-chat/chorus/stargazers
-[issues-shield]: https://img.shields.io/github/issues/polyphony-chat/chorus.svg?style=plastic
+[issues-shield]: https://img.shields.io/github/issues/polyphony-chat/chorus.svg?style=flat
[issues-url]: https://github.com/polyphony-chat/chorus/issues
-[license-shield]: https://img.shields.io/github/license/polyphony-chat/chorus.svg?style=plastic
+[license-shield]: https://img.shields.io/github/license/polyphony-chat/chorus.svg?style=f;at
[license-url]: https://github.com/polyphony-chat/chorus/blob/master/LICENSE
+[Discord]: https://dcbadge.vercel.app/api/server/m3FpcapGDD?style=flat
+[Discord-invite]: https://discord.com/invite/m3FpcapGDD
From 2eb7c8edbc0916f2fecbd03881c9d9ffde28f25d Mon Sep 17 00:00:00 2001
From: bitfl0wer
Date: Thu, 25 May 2023 18:46:59 +0200
Subject: [PATCH 02/11] add types from polyphony-types
---
types/config/mod.rs | 187 ++++++++++++++
types/config/types/api_configuration.rs | 24 ++
types/config/types/cdn_configuration.rs | 25 ++
types/config/types/defaults_configuration.rs | 10 +
types/config/types/email_configuration.rs | 27 ++
types/config/types/endpoint_configuration.rs | 9 +
.../types/external_tokens_configuration.rs | 7 +
types/config/types/general_configuration.rs | 35 +++
types/config/types/gif_configuration.rs | 26 ++
types/config/types/guild_configuration.rs | 126 +++++++++
types/config/types/kafka_configuration.rs | 10 +
types/config/types/limit_configuration.rs | 17 ++
types/config/types/login_configuration.rs | 8 +
types/config/types/metrics_configuration.rs | 13 +
types/config/types/mod.rs | 21 ++
.../types/password_reset_configuration.rs | 7 +
types/config/types/rabbit_mq_configuration.rs | 7 +
types/config/types/region_configuration.rs | 29 +++
types/config/types/register_configuration.rs | 41 +++
types/config/types/security_configuration.rs | 42 +++
types/config/types/sentry_configuration.rs | 28 ++
types/config/types/subconfigs/client/mod.rs | 17 ++
.../config/types/subconfigs/defaults/guild.rs | 23 ++
types/config/types/subconfigs/defaults/mod.rs | 2 +
.../config/types/subconfigs/defaults/user.rs | 19 ++
.../config/types/subconfigs/email/mailgun.rs | 8 +
.../config/types/subconfigs/email/mailjet.rs | 8 +
types/config/types/subconfigs/email/mod.rs | 4 +
.../config/types/subconfigs/email/sendgrid.rs | 7 +
types/config/types/subconfigs/email/smtp.rs | 10 +
.../config/types/subconfigs/guild/autojoin.rs | 22 ++
.../types/subconfigs/guild/discovery.rs | 21 ++
types/config/types/subconfigs/guild/mod.rs | 2 +
types/config/types/subconfigs/kafka/mod.rs | 7 +
.../config/types/subconfigs/limits/channel.rs | 19 ++
.../config/types/subconfigs/limits/global.rs | 41 +++
types/config/types/subconfigs/limits/guild.rs | 23 ++
.../config/types/subconfigs/limits/message.rs | 26 ++
types/config/types/subconfigs/limits/mod.rs | 7 +
.../subconfigs/limits/ratelimits/auth.rs | 28 ++
.../types/subconfigs/limits/ratelimits/mod.rs | 14 +
.../subconfigs/limits/ratelimits/route.rs | 37 +++
types/config/types/subconfigs/limits/rates.rs | 41 +++
types/config/types/subconfigs/limits/user.rs | 19 ++
types/config/types/subconfigs/mod.rs | 9 +
types/config/types/subconfigs/region/mod.rs | 21 ++
.../subconfigs/register/date_of_birth.rs | 16 ++
.../config/types/subconfigs/register/email.rs | 21 ++
types/config/types/subconfigs/register/mod.rs | 7 +
.../types/subconfigs/register/password.rs | 23 ++
.../types/subconfigs/security/captcha.rs | 27 ++
types/config/types/subconfigs/security/mod.rs | 5 +
.../types/subconfigs/security/twofactor.rs | 15 ++
types/config/types/template_configuration.rs | 21 ++
types/entities/application.rs | 140 ++++++++++
types/entities/attachment.rs | 113 +++++++++
types/entities/channel.rs | 116 +++++++++
types/entities/config.rs | 34 +++
types/entities/emoji.rs | 15 ++
types/entities/guild.rs | 117 +++++++++
types/entities/guild_member.rs | 19 ++
types/entities/integration.rs | 36 +++
types/entities/message.rs | 185 ++++++++++++++
types/entities/mod.rs | 37 +++
types/entities/role.rs | 28 ++
types/entities/security_key.rs | 26 ++
types/entities/sticker.rs | 27 ++
types/entities/team.rs | 20 ++
types/entities/template.rs | 24 ++
types/entities/user.rs | 238 +++++++++++++++++
types/entities/user_settings.rs | 133 ++++++++++
types/entities/voice_state.rs | 30 +++
types/entities/webhook.rs | 32 +++
types/errors.rs | 54 ++++
types/events/channel.rs | 41 +++
types/events/guild.rs | 41 +++
types/events/heartbeat.rs | 17 ++
types/events/hello.rs | 17 ++
types/events/identify.rs | 22 ++
types/events/message.rs | 101 ++++++++
types/events/mod.rs | 41 +++
types/events/presence.rs | 24 ++
types/events/ready.rs | 15 ++
types/events/request_members.rs | 15 ++
types/events/resume.rs | 11 +
types/events/thread.rs | 82 ++++++
types/events/user.rs | 12 +
types/events/voice_status.rs | 13 +
types/interfaces/activity.rs | 57 +++++
types/interfaces/connected_account.rs | 0
types/interfaces/guild_welcome_screen.rs | 17 ++
types/interfaces/interaction.rs | 39 +++
types/interfaces/mod.rs | 11 +
types/interfaces/status.rs | 9 +
types/lib.rs | 7 +
types/schema/apierror.rs | 72 ++++++
types/schema/auth.rs | 240 ++++++++++++++++++
types/schema/channel.rs | 27 ++
types/schema/guild.rs | 14 +
types/schema/message.rs | 47 ++++
types/schema/mod.rs | 103 ++++++++
types/schema/user.rs | 16 ++
types/utils/jwt.rs | 44 ++++
types/utils/mod.rs | 8 +
types/utils/regexes.rs | 12 +
types/utils/rights.rs | 127 +++++++++
types/utils/snowflake.rs | 160 ++++++++++++
107 files changed, 4155 insertions(+)
create mode 100644 types/config/mod.rs
create mode 100644 types/config/types/api_configuration.rs
create mode 100644 types/config/types/cdn_configuration.rs
create mode 100644 types/config/types/defaults_configuration.rs
create mode 100644 types/config/types/email_configuration.rs
create mode 100644 types/config/types/endpoint_configuration.rs
create mode 100644 types/config/types/external_tokens_configuration.rs
create mode 100644 types/config/types/general_configuration.rs
create mode 100644 types/config/types/gif_configuration.rs
create mode 100644 types/config/types/guild_configuration.rs
create mode 100644 types/config/types/kafka_configuration.rs
create mode 100644 types/config/types/limit_configuration.rs
create mode 100644 types/config/types/login_configuration.rs
create mode 100644 types/config/types/metrics_configuration.rs
create mode 100644 types/config/types/mod.rs
create mode 100644 types/config/types/password_reset_configuration.rs
create mode 100644 types/config/types/rabbit_mq_configuration.rs
create mode 100644 types/config/types/region_configuration.rs
create mode 100644 types/config/types/register_configuration.rs
create mode 100644 types/config/types/security_configuration.rs
create mode 100644 types/config/types/sentry_configuration.rs
create mode 100644 types/config/types/subconfigs/client/mod.rs
create mode 100644 types/config/types/subconfigs/defaults/guild.rs
create mode 100644 types/config/types/subconfigs/defaults/mod.rs
create mode 100644 types/config/types/subconfigs/defaults/user.rs
create mode 100644 types/config/types/subconfigs/email/mailgun.rs
create mode 100644 types/config/types/subconfigs/email/mailjet.rs
create mode 100644 types/config/types/subconfigs/email/mod.rs
create mode 100644 types/config/types/subconfigs/email/sendgrid.rs
create mode 100644 types/config/types/subconfigs/email/smtp.rs
create mode 100644 types/config/types/subconfigs/guild/autojoin.rs
create mode 100644 types/config/types/subconfigs/guild/discovery.rs
create mode 100644 types/config/types/subconfigs/guild/mod.rs
create mode 100644 types/config/types/subconfigs/kafka/mod.rs
create mode 100644 types/config/types/subconfigs/limits/channel.rs
create mode 100644 types/config/types/subconfigs/limits/global.rs
create mode 100644 types/config/types/subconfigs/limits/guild.rs
create mode 100644 types/config/types/subconfigs/limits/message.rs
create mode 100644 types/config/types/subconfigs/limits/mod.rs
create mode 100644 types/config/types/subconfigs/limits/ratelimits/auth.rs
create mode 100644 types/config/types/subconfigs/limits/ratelimits/mod.rs
create mode 100644 types/config/types/subconfigs/limits/ratelimits/route.rs
create mode 100644 types/config/types/subconfigs/limits/rates.rs
create mode 100644 types/config/types/subconfigs/limits/user.rs
create mode 100644 types/config/types/subconfigs/mod.rs
create mode 100644 types/config/types/subconfigs/region/mod.rs
create mode 100644 types/config/types/subconfigs/register/date_of_birth.rs
create mode 100644 types/config/types/subconfigs/register/email.rs
create mode 100644 types/config/types/subconfigs/register/mod.rs
create mode 100644 types/config/types/subconfigs/register/password.rs
create mode 100644 types/config/types/subconfigs/security/captcha.rs
create mode 100644 types/config/types/subconfigs/security/mod.rs
create mode 100644 types/config/types/subconfigs/security/twofactor.rs
create mode 100644 types/config/types/template_configuration.rs
create mode 100644 types/entities/application.rs
create mode 100644 types/entities/attachment.rs
create mode 100644 types/entities/channel.rs
create mode 100644 types/entities/config.rs
create mode 100644 types/entities/emoji.rs
create mode 100644 types/entities/guild.rs
create mode 100644 types/entities/guild_member.rs
create mode 100644 types/entities/integration.rs
create mode 100644 types/entities/message.rs
create mode 100644 types/entities/mod.rs
create mode 100644 types/entities/role.rs
create mode 100644 types/entities/security_key.rs
create mode 100644 types/entities/sticker.rs
create mode 100644 types/entities/team.rs
create mode 100644 types/entities/template.rs
create mode 100644 types/entities/user.rs
create mode 100644 types/entities/user_settings.rs
create mode 100644 types/entities/voice_state.rs
create mode 100644 types/entities/webhook.rs
create mode 100644 types/errors.rs
create mode 100644 types/events/channel.rs
create mode 100644 types/events/guild.rs
create mode 100644 types/events/heartbeat.rs
create mode 100644 types/events/hello.rs
create mode 100644 types/events/identify.rs
create mode 100644 types/events/message.rs
create mode 100644 types/events/mod.rs
create mode 100644 types/events/presence.rs
create mode 100644 types/events/ready.rs
create mode 100644 types/events/request_members.rs
create mode 100644 types/events/resume.rs
create mode 100644 types/events/thread.rs
create mode 100644 types/events/user.rs
create mode 100644 types/events/voice_status.rs
create mode 100644 types/interfaces/activity.rs
create mode 100644 types/interfaces/connected_account.rs
create mode 100644 types/interfaces/guild_welcome_screen.rs
create mode 100644 types/interfaces/interaction.rs
create mode 100644 types/interfaces/mod.rs
create mode 100644 types/interfaces/status.rs
create mode 100644 types/lib.rs
create mode 100644 types/schema/apierror.rs
create mode 100644 types/schema/auth.rs
create mode 100644 types/schema/channel.rs
create mode 100644 types/schema/guild.rs
create mode 100644 types/schema/message.rs
create mode 100644 types/schema/mod.rs
create mode 100644 types/schema/user.rs
create mode 100644 types/utils/jwt.rs
create mode 100644 types/utils/mod.rs
create mode 100644 types/utils/regexes.rs
create mode 100644 types/utils/rights.rs
create mode 100644 types/utils/snowflake.rs
diff --git a/types/config/mod.rs b/types/config/mod.rs
new file mode 100644
index 0000000..97b830a
--- /dev/null
+++ b/types/config/mod.rs
@@ -0,0 +1,187 @@
+use serde::{Deserialize, Serialize};
+use serde_json::{Map, Value};
+
+pub use crate::{
+ config::types::{
+ api_configuration::ApiConfiguration, cdn_configuration::CdnConfiguration,
+ defaults_configuration::DefaultsConfiguration, email_configuration::EmailConfiguration,
+ endpoint_configuration::EndpointConfiguration,
+ external_tokens_configuration::ExternalTokensConfiguration,
+ general_configuration::GeneralConfiguration, gif_configuration::GifConfiguration,
+ guild_configuration::GuildConfiguration, kafka_configuration::KafkaConfiguration,
+ limit_configuration::LimitsConfiguration, login_configuration::LoginConfiguration,
+ metrics_configuration::MetricsConfiguration,
+ password_reset_configuration::PasswordResetConfiguration,
+ rabbit_mq_configuration::RabbitMQConfiguration, region_configuration::RegionConfiguration,
+ register_configuration::RegisterConfiguration,
+ security_configuration::SecurityConfiguration, sentry_configuration::SentryConfiguration,
+ template_configuration::TemplateConfiguration,
+ },
+ entities::ConfigEntity,
+};
+
+mod types;
+
+#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ConfigValue {
+ pub gateway: EndpointConfiguration,
+ pub cdn: CdnConfiguration,
+ pub api: ApiConfiguration,
+ pub general: GeneralConfiguration,
+ pub limits: LimitsConfiguration,
+ pub security: SecurityConfiguration,
+ pub login: LoginConfiguration,
+ pub register: RegisterConfiguration,
+ pub regions: RegionConfiguration,
+ pub guild: GuildConfiguration,
+ pub gif: GifConfiguration,
+ pub rabbitmq: RabbitMQConfiguration,
+ pub kafka: KafkaConfiguration,
+ pub templates: TemplateConfiguration,
+ pub metrics: MetricsConfiguration,
+ pub sentry: SentryConfiguration,
+ pub defaults: DefaultsConfiguration,
+ pub external: ExternalTokensConfiguration,
+ pub email: EmailConfiguration,
+ pub password_reset: PasswordResetConfiguration,
+}
+
+impl ConfigValue {
+ pub fn to_pairs(&self) -> Vec {
+ let v = serde_json::json!(self);
+
+ generate_pairs(&v, "")
+ }
+
+ pub fn from_pairs(pairs: Vec) -> Self {
+ pairs_to_config(pairs)
+ }
+}
+
+fn generate_pairs(obj: &Value, key: &str) -> Vec {
+ let mut pairs = Vec::new();
+ match obj {
+ Value::Object(map) => {
+ for (k, v) in map {
+ let new_key = if key.is_empty() {
+ k.to_string()
+ } else {
+ format!("{}_{}", key, k)
+ };
+ pairs.extend(generate_pairs(v, &new_key));
+ }
+ }
+ Value::Array(arr) => {
+ for (i, v) in arr.iter().enumerate() {
+ let new_key = format!("{}_{}", key, i);
+ pairs.extend(generate_pairs(v, &new_key));
+ }
+ }
+ _ => pairs.push(ConfigEntity {
+ key: key.to_string(),
+ value: Some(obj.clone()),
+ }),
+ }
+ pairs
+}
+
+fn pairs_to_config(pairs: Vec) -> ConfigValue {
+ let mut value = Value::Object(Map::new());
+
+ for p in pairs {
+ let keys: Vec<&str> = p.key.split('_').collect();
+ let mut path = vec![];
+
+ for (i, &key) in keys.iter().enumerate() {
+ path.push(key);
+
+ if i == keys.len() - 1 {
+ insert_into(&mut value, &path, p.value.clone().unwrap_or(Value::Null));
+ } else if keys[i+1].parse::().is_ok() {
+ if !path_exists(&value, &path) {
+ insert_into(&mut value, &path, Value::Array(Vec::new()));
+ }
+ } else if !path_exists(&value, &path) {
+ insert_into(&mut value, &path, Value::Object(Map::new()));
+ }
+ }
+ }
+
+ serde_json::from_value(value).unwrap()
+}
+
+fn path_exists(value: &Value, path: &[&str]) -> bool {
+ let mut current = value;
+
+ for &key in path {
+ match current {
+ Value::Object(map) => {
+ if let Some(v) = map.get(key) {
+ current = v;
+ } else {
+ return false;
+ }
+ },
+ Value::Array(arr) => {
+ if let Ok(index) = key.parse::() {
+ if let Some(v) = arr.get(index) {
+ current = v;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ },
+ _ => return false,
+ }
+ }
+
+ true
+}
+
+fn insert_into(value: &mut Value, path: &[&str], new_value: Value) {
+ let last_key = path.last().unwrap();
+ let parent_path = &path[0..path.len()-1];
+
+ let mut current = value;
+
+ for &key in parent_path {
+ current = match current {
+ Value::Object(map) => map.get_mut(key).unwrap(),
+ Value::Array(arr) => arr.get_mut(key.parse::().unwrap()).unwrap(),
+ _ => unreachable!(),
+ };
+ }
+
+ match current {
+ Value::Object(map) => {
+ map.insert((*last_key).to_string(), new_value);
+ },
+ Value::Array(arr) => {
+ let index = last_key.parse::().unwrap();
+ if index >= arr.len() {
+ arr.resize(index + 1, Value::Null);
+ }
+ arr[index] = new_value;
+ },
+ _ => unreachable!(),
+ };
+}
+
+#[cfg(test)]
+mod test {
+ use crate::config::{generate_pairs, pairs_to_config, ConfigValue};
+
+ #[test]
+ fn test_pairs() {
+ let c = ConfigValue::default();
+ let v = serde_json::json!(&c);
+
+ let pairs = generate_pairs(&v, "");
+
+ let cfg = pairs_to_config(pairs);
+ assert_eq!(cfg, c)
+ }
+}
diff --git a/types/config/types/api_configuration.rs b/types/config/types/api_configuration.rs
new file mode 100644
index 0000000..2d617fe
--- /dev/null
+++ b/types/config/types/api_configuration.rs
@@ -0,0 +1,24 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+pub struct ApiConfiguration {
+ pub default_version: String,
+ pub active_versions: Vec,
+ pub endpoint_public: Option,
+}
+
+impl Default for ApiConfiguration {
+ fn default() -> Self {
+ Self {
+ default_version: String::from("9"),
+ active_versions: vec![
+ String::from("6"),
+ String::from("7"),
+ String::from("8"),
+ String::from("9"),
+ ],
+ endpoint_public: None,
+ }
+ }
+}
diff --git a/types/config/types/cdn_configuration.rs b/types/config/types/cdn_configuration.rs
new file mode 100644
index 0000000..5c76273
--- /dev/null
+++ b/types/config/types/cdn_configuration.rs
@@ -0,0 +1,25 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct CdnConfiguration {
+ pub resize_height_max: u64,
+ pub resize_width_max: u64,
+ pub imagor_server_url: Option,
+
+ pub endpoint_public: Option,
+ pub endpoint_private: Option,
+}
+
+impl Default for CdnConfiguration {
+ fn default() -> Self {
+ Self {
+ resize_height_max: 1000,
+ resize_width_max: 1000,
+ imagor_server_url: None,
+
+ endpoint_private: None,
+ endpoint_public: None,
+ }
+ }
+}
diff --git a/types/config/types/defaults_configuration.rs b/types/config/types/defaults_configuration.rs
new file mode 100644
index 0000000..b89b304
--- /dev/null
+++ b/types/config/types/defaults_configuration.rs
@@ -0,0 +1,10 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::defaults::{guild::GuildDefaults, user::UserDefaults};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct DefaultsConfiguration {
+ pub guild: GuildDefaults,
+ pub user: UserDefaults,
+}
diff --git a/types/config/types/email_configuration.rs b/types/config/types/email_configuration.rs
new file mode 100644
index 0000000..3025487
--- /dev/null
+++ b/types/config/types/email_configuration.rs
@@ -0,0 +1,27 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::email::{
+ mailgun::MailGunConfiguration, mailjet::MailJetConfiguration, sendgrid::SendGridConfiguration,
+ smtp::SMTPConfiguration,
+};
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
+pub enum EmailProvider {
+ Smtp,
+ MailGun,
+ MailJet,
+ SendGrid,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+#[derive(Default)]
+pub struct EmailConfiguration {
+ pub provider: Option,
+ pub smtp: SMTPConfiguration,
+ pub mailgun: MailGunConfiguration,
+ pub mailjet: MailJetConfiguration,
+ pub sendgrid: SendGridConfiguration,
+}
+
+
diff --git a/types/config/types/endpoint_configuration.rs b/types/config/types/endpoint_configuration.rs
new file mode 100644
index 0000000..b484791
--- /dev/null
+++ b/types/config/types/endpoint_configuration.rs
@@ -0,0 +1,9 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct EndpointConfiguration {
+ pub endpoint_client: Option,
+ pub endpoint_private: Option,
+ pub endpoint_public: Option,
+}
diff --git a/types/config/types/external_tokens_configuration.rs b/types/config/types/external_tokens_configuration.rs
new file mode 100644
index 0000000..f417b2f
--- /dev/null
+++ b/types/config/types/external_tokens_configuration.rs
@@ -0,0 +1,7 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ExternalTokensConfiguration {
+ pub twitter: Option,
+}
diff --git a/types/config/types/general_configuration.rs b/types/config/types/general_configuration.rs
new file mode 100644
index 0000000..f67fdf2
--- /dev/null
+++ b/types/config/types/general_configuration.rs
@@ -0,0 +1,35 @@
+use serde::{Deserialize, Serialize};
+
+use crate::utils::Snowflake;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GeneralConfiguration {
+ pub instance_name: String,
+ pub instance_description: Option,
+ pub front_page: Option,
+ pub tos_page: Option,
+ pub correspondence_email: Option,
+ pub correspondence_user_id: Option,
+ pub image: Option,
+ pub instance_id: Option,
+ pub auto_create_bot_users: Option,
+}
+
+impl Default for GeneralConfiguration {
+ fn default() -> Self {
+ Self {
+ instance_name: String::from("Spacebar Instance"),
+ instance_description: Some(String::from(
+ "This is a Spacebar instance made in the pre-release days",
+ )),
+ front_page: None,
+ tos_page: None,
+ correspondence_email: None,
+ correspondence_user_id: None,
+ image: None,
+ instance_id: Some(Snowflake::generate()),
+ auto_create_bot_users: Some(false),
+ }
+ }
+}
diff --git a/types/config/types/gif_configuration.rs b/types/config/types/gif_configuration.rs
new file mode 100644
index 0000000..8644fb4
--- /dev/null
+++ b/types/config/types/gif_configuration.rs
@@ -0,0 +1,26 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum GifProvider {
+ #[default]
+ Tenor,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GifConfiguration {
+ pub enabled: bool,
+ pub provider: GifProvider,
+ pub api_key: Option,
+}
+
+impl Default for GifConfiguration {
+ fn default() -> Self {
+ Self {
+ enabled: true,
+ provider: GifProvider::Tenor,
+ api_key: Some(String::from("LIVDSRZULELA")),
+ }
+ }
+}
diff --git a/types/config/types/guild_configuration.rs b/types/config/types/guild_configuration.rs
new file mode 100644
index 0000000..536396e
--- /dev/null
+++ b/types/config/types/guild_configuration.rs
@@ -0,0 +1,126 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::guild::{
+ autojoin::AutoJoinConfiguration, discovery::DiscoverConfiguration,
+};
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+pub enum GuildFeatures {
+ ActivitiesAlpha,
+ ActivitiesEmployee,
+ ActivitiesInternalDev,
+ AnimatedBanner,
+ AnimatedIcon,
+ ApplicationCommandPermissionsV2,
+ AutoModeration,
+ AutoModTriggerKeywordFilter,
+ AutoModTriggerMLSpamFilter,
+ AutoModTriggerSpamLinkFilter,
+ AutoModTriggerUserProfile,
+ Banner,
+ BFG,
+ BoostingTiersExperimentMediumGuild,
+ BoostingTiersExperimentSmallGuild,
+ BotDeveloperEarlyAccess,
+ BurstReactions,
+ CommunityCanary,
+ CommunityExpLargeGated,
+ CommunityExpLargeUngated,
+ CommunityExpMedium,
+ ChannelEmojisGenerated,
+ ChannelHighlights,
+ ChannelHighlightsDisabled,
+ ClydeEnabled,
+ ClydeExperimentEnabled,
+ ClydeDisabled,
+ Community,
+ CreatorAcceptedNewTerms,
+ CreatorMonetizable,
+ CreatorMonetizableDisabled,
+ CreatorMonetizablePendingNewOwnerOnboarding,
+ CreatorMonetizableProvisional,
+ CreatorMonetizableRestricted,
+ CreatorMonetizableWhiteglove,
+ CreatorMonetizableApplicationAllowlist,
+ CreateStorePage,
+ DeveloperSupportServer,
+ DiscoverableDisabled,
+ Discoverable,
+ EnabledDiscoverableBefore,
+ ExposedToActivitiesWTPExperiment,
+ GuestsEnabled,
+ GuildAutomodDefaultList,
+ GuildCommunicationDisabledGuilds,
+ GuildHomeDeprecationOverride,
+ GuildHomeOverride,
+ GuildHomeTest,
+ GuildMemberVerificationExperiment,
+ GuildOnboarding,
+ GuildOnboardingAdminOnly,
+ GuildOnboardingEverEnabled,
+ GuildOnboardingHasPrompts,
+ GuildRoleSubscription,
+ GuildRoleSubscriptionPurchaseFeedbackLoop,
+ GuildRoleSubscriptionTrials,
+ GuildServerGuide,
+ GuildWebPageVanityURL,
+ HadEarlyActivitiesAccess,
+ HasDirectoryEntry,
+ HideFromExperimentUI,
+ Hub,
+ IncreasedThreadLimit,
+ InternalEmployeeOnly,
+ InviteSplash,
+ InvitesDisabled,
+ LinkedToHub,
+ MarketplacesConnectionRoles,
+ MemberProfiles,
+ MemberVerificationGateEnabled,
+ MemberVerificationManualApproval,
+ MobileWebRoleSubscriptionPurchasePage,
+ MonetizationEnabled,
+ MoreEmoji,
+ MoreStickers,
+ News,
+ NewThreadPermissions,
+ Partnered,
+ PremiumTier3Override,
+ PreviewEnabled,
+ RaidAlertsDisabled,
+ RelayEnabled,
+ RestrictSpamRiskGuild,
+ RoleIcons,
+ RoleSubscriptionsAvailableForPurchase,
+ RoleSubscriptionsEnabled,
+ RoleSubscriptionsEnabledForPurchase,
+ Shard,
+ SharedCanvasFriendsAndFamilyTest,
+ Soundboard,
+ SummariesEnabled,
+ SummariesEnabledGA,
+ SummariesDisabledByUser,
+ SummariesEnabledByUser,
+ TextInStageEnabled,
+ TextInVoiceEnabled,
+ ThreadsEnabledTesting,
+ ThreadsEnabled,
+ ThreadDefaultAutoArchiveDuration,
+ ThreadsOnlyChannel,
+ TicketedEventsEnabled,
+ TicketingEnabled,
+ VanityUrls,
+ Verified,
+ VIPRegions,
+ VoiceChannelEffects,
+ WelcomeScreenEnabled,
+}
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GuildConfiguration {
+ pub discovery: DiscoverConfiguration,
+ pub auto_join: AutoJoinConfiguration,
+ #[serde(default)]
+ pub default_features: Vec,
+}
diff --git a/types/config/types/kafka_configuration.rs b/types/config/types/kafka_configuration.rs
new file mode 100644
index 0000000..050ffc3
--- /dev/null
+++ b/types/config/types/kafka_configuration.rs
@@ -0,0 +1,10 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::kafka::KafkaBroker;
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct KafkaConfiguration {
+ #[serde(default)]
+ pub brokers: Option>,
+}
diff --git a/types/config/types/limit_configuration.rs b/types/config/types/limit_configuration.rs
new file mode 100644
index 0000000..ad2ad17
--- /dev/null
+++ b/types/config/types/limit_configuration.rs
@@ -0,0 +1,17 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::limits::{
+ channel::ChannelLimits, global::GlobalRateLimits, guild::GuildLimits, message::MessageLimits,
+ rates::RateLimits, user::UserLimits,
+};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct LimitsConfiguration {
+ pub user: UserLimits,
+ pub guild: GuildLimits,
+ pub message: MessageLimits,
+ pub channel: ChannelLimits,
+ pub rate: RateLimits,
+ pub absolute_rate: GlobalRateLimits,
+}
diff --git a/types/config/types/login_configuration.rs b/types/config/types/login_configuration.rs
new file mode 100644
index 0000000..a2b1039
--- /dev/null
+++ b/types/config/types/login_configuration.rs
@@ -0,0 +1,8 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct LoginConfiguration {
+ pub require_captcha: bool,
+ pub require_verification: bool,
+}
diff --git a/types/config/types/metrics_configuration.rs b/types/config/types/metrics_configuration.rs
new file mode 100644
index 0000000..336ac84
--- /dev/null
+++ b/types/config/types/metrics_configuration.rs
@@ -0,0 +1,13 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MetricsConfiguration {
+ pub timeout: u64,
+}
+
+impl Default for MetricsConfiguration {
+ fn default() -> Self {
+ Self { timeout: 30000 }
+ }
+}
diff --git a/types/config/types/mod.rs b/types/config/types/mod.rs
new file mode 100644
index 0000000..dce4eb0
--- /dev/null
+++ b/types/config/types/mod.rs
@@ -0,0 +1,21 @@
+pub mod api_configuration;
+pub mod cdn_configuration;
+pub mod defaults_configuration;
+pub mod email_configuration;
+pub mod endpoint_configuration;
+pub mod external_tokens_configuration;
+pub mod general_configuration;
+pub mod gif_configuration;
+pub mod guild_configuration;
+pub mod kafka_configuration;
+pub mod limit_configuration;
+pub mod login_configuration;
+pub mod metrics_configuration;
+pub mod password_reset_configuration;
+pub mod rabbit_mq_configuration;
+pub mod region_configuration;
+pub mod register_configuration;
+pub mod security_configuration;
+pub mod sentry_configuration;
+pub mod subconfigs;
+pub mod template_configuration;
diff --git a/types/config/types/password_reset_configuration.rs b/types/config/types/password_reset_configuration.rs
new file mode 100644
index 0000000..4dddae9
--- /dev/null
+++ b/types/config/types/password_reset_configuration.rs
@@ -0,0 +1,7 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PasswordResetConfiguration {
+ pub require_captcha: bool,
+}
diff --git a/types/config/types/rabbit_mq_configuration.rs b/types/config/types/rabbit_mq_configuration.rs
new file mode 100644
index 0000000..2437055
--- /dev/null
+++ b/types/config/types/rabbit_mq_configuration.rs
@@ -0,0 +1,7 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RabbitMQConfiguration {
+ pub host: Option,
+}
diff --git a/types/config/types/region_configuration.rs b/types/config/types/region_configuration.rs
new file mode 100644
index 0000000..065a8f7
--- /dev/null
+++ b/types/config/types/region_configuration.rs
@@ -0,0 +1,29 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::region::Region;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RegionConfiguration {
+ pub default: String,
+ pub use_default_as_optimal: bool,
+ pub available: Vec,
+}
+
+impl Default for RegionConfiguration {
+ fn default() -> Self {
+ Self {
+ default: String::from("spacebar"),
+ use_default_as_optimal: true,
+ available: vec![Region {
+ id: String::from("spacebar"),
+ name: String::from("spacebar"),
+ endpoint: String::from("127.0.0.1:3004"),
+ location: None,
+ vip: false,
+ custom: false,
+ deprecated: false,
+ }],
+ }
+ }
+}
diff --git a/types/config/types/register_configuration.rs b/types/config/types/register_configuration.rs
new file mode 100644
index 0000000..304299a
--- /dev/null
+++ b/types/config/types/register_configuration.rs
@@ -0,0 +1,41 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::register::{
+ DateOfBirthConfiguration, PasswordConfiguration, RegistrationEmailConfiguration,
+};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RegisterConfiguration {
+ pub email: RegistrationEmailConfiguration,
+ pub date_of_birth: DateOfBirthConfiguration,
+ pub password: PasswordConfiguration,
+ pub disabled: bool,
+ pub require_captcha: bool,
+ pub require_invite: bool,
+ pub guests_require_invite: bool,
+ pub allow_new_registration: bool,
+ pub allow_multiple_accounts: bool,
+ pub block_proxies: bool,
+ pub incrementing_discriminators: bool,
+ pub default_rights: String,
+}
+
+impl Default for RegisterConfiguration {
+ fn default() -> Self {
+ Self {
+ email: RegistrationEmailConfiguration::default(),
+ date_of_birth: DateOfBirthConfiguration::default(),
+ password: PasswordConfiguration::default(),
+ disabled: false,
+ require_captcha: true,
+ require_invite: false,
+ guests_require_invite: true,
+ allow_new_registration: true,
+ allow_multiple_accounts: true,
+ block_proxies: true,
+ incrementing_discriminators: false,
+ default_rights: String::from("875069521787904"),
+ }
+ }
+}
diff --git a/types/config/types/security_configuration.rs b/types/config/types/security_configuration.rs
new file mode 100644
index 0000000..65008da
--- /dev/null
+++ b/types/config/types/security_configuration.rs
@@ -0,0 +1,42 @@
+use base64::Engine;
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::security::{CaptchaConfiguration, TwoFactorConfiguration};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SecurityConfiguration {
+ pub captcha: CaptchaConfiguration,
+ pub two_factor: TwoFactorConfiguration,
+ pub auto_update: bool,
+ pub request_signature: String,
+ pub jwt_secret: String,
+ pub forwarded_for: Option,
+ pub ipdata_api_key: Option,
+ pub mfa_backup_code_count: u8,
+ pub stats_world_readable: bool,
+ pub default_registration_token_expiration: u64,
+}
+
+impl Default for SecurityConfiguration {
+ fn default() -> Self {
+ let mut req_sig: [u8; 32] = [0; 32];
+ let _ = openssl::rand::rand_bytes(&mut req_sig);
+ let mut jwt_secret: [u8; 256] = [0; 256];
+ let _ = openssl::rand::rand_bytes(&mut jwt_secret);
+ Self {
+ captcha: Default::default(),
+ two_factor: Default::default(),
+ auto_update: true,
+ request_signature: base64::engine::general_purpose::STANDARD.encode(req_sig),
+ jwt_secret: base64::engine::general_purpose::STANDARD.encode(jwt_secret),
+ forwarded_for: None,
+ ipdata_api_key: Some(String::from(
+ "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9",
+ )),
+ mfa_backup_code_count: 10,
+ stats_world_readable: true,
+ default_registration_token_expiration: 1000 * 60 * 60 * 24 * 7,
+ }
+ }
+}
diff --git a/types/config/types/sentry_configuration.rs b/types/config/types/sentry_configuration.rs
new file mode 100644
index 0000000..256bab9
--- /dev/null
+++ b/types/config/types/sentry_configuration.rs
@@ -0,0 +1,28 @@
+use std::ffi::OsString;
+
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SentryConfiguration {
+ pub enabled: bool,
+ pub endpoint: String,
+ pub trace_sample_rate: f64,
+ pub environment: String,
+}
+
+impl Default for SentryConfiguration {
+ fn default() -> Self {
+ Self {
+ enabled: false,
+ endpoint: String::from(
+ "https://241c6fb08adb469da1bb82522b25c99f@sentry.quartzinc.space/3",
+ ),
+ trace_sample_rate: 1.0,
+ environment: hostname::get()
+ .unwrap_or_else(|_| OsString::new())
+ .to_string_lossy()
+ .to_string(),
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/client/mod.rs b/types/config/types/subconfigs/client/mod.rs
new file mode 100644
index 0000000..5d3d304
--- /dev/null
+++ b/types/config/types/subconfigs/client/mod.rs
@@ -0,0 +1,17 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ClientReleaseConfiguration {
+ pub use_local_release: bool,
+ pub upstream_version: String,
+}
+
+impl Default for ClientReleaseConfiguration {
+ fn default() -> Self {
+ Self {
+ use_local_release: true,
+ upstream_version: String::from("0.0.264"),
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/defaults/guild.rs b/types/config/types/subconfigs/defaults/guild.rs
new file mode 100644
index 0000000..966c7af
--- /dev/null
+++ b/types/config/types/subconfigs/defaults/guild.rs
@@ -0,0 +1,23 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GuildDefaults {
+ pub max_presences: u64,
+ pub max_video_channel_users: u16,
+ pub afk_timeout: u16,
+ pub default_message_notifications: u8,
+ pub explicit_content_filter: u8,
+}
+
+impl Default for GuildDefaults {
+ fn default() -> Self {
+ Self {
+ max_presences: 250_000,
+ max_video_channel_users: 200,
+ afk_timeout: 300,
+ default_message_notifications: 1,
+ explicit_content_filter: 0,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/defaults/mod.rs b/types/config/types/subconfigs/defaults/mod.rs
new file mode 100644
index 0000000..56d877f
--- /dev/null
+++ b/types/config/types/subconfigs/defaults/mod.rs
@@ -0,0 +1,2 @@
+pub mod guild;
+pub mod user;
diff --git a/types/config/types/subconfigs/defaults/user.rs b/types/config/types/subconfigs/defaults/user.rs
new file mode 100644
index 0000000..635d6d4
--- /dev/null
+++ b/types/config/types/subconfigs/defaults/user.rs
@@ -0,0 +1,19 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct UserDefaults {
+ pub premium: bool,
+ pub premium_type: u8,
+ pub verified: bool,
+}
+
+impl Default for UserDefaults {
+ fn default() -> Self {
+ Self {
+ premium: true,
+ premium_type: 2,
+ verified: true,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/email/mailgun.rs b/types/config/types/subconfigs/email/mailgun.rs
new file mode 100644
index 0000000..636e462
--- /dev/null
+++ b/types/config/types/subconfigs/email/mailgun.rs
@@ -0,0 +1,8 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MailGunConfiguration {
+ pub api_key: Option,
+ pub domain: Option,
+}
diff --git a/types/config/types/subconfigs/email/mailjet.rs b/types/config/types/subconfigs/email/mailjet.rs
new file mode 100644
index 0000000..4e505c1
--- /dev/null
+++ b/types/config/types/subconfigs/email/mailjet.rs
@@ -0,0 +1,8 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MailJetConfiguration {
+ pub api_key: Option,
+ pub api_secret: Option,
+}
diff --git a/types/config/types/subconfigs/email/mod.rs b/types/config/types/subconfigs/email/mod.rs
new file mode 100644
index 0000000..21253fd
--- /dev/null
+++ b/types/config/types/subconfigs/email/mod.rs
@@ -0,0 +1,4 @@
+pub mod mailgun;
+pub mod mailjet;
+pub mod sendgrid;
+pub mod smtp;
diff --git a/types/config/types/subconfigs/email/sendgrid.rs b/types/config/types/subconfigs/email/sendgrid.rs
new file mode 100644
index 0000000..879c719
--- /dev/null
+++ b/types/config/types/subconfigs/email/sendgrid.rs
@@ -0,0 +1,7 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct SendGridConfiguration {
+ pub api_key: Option,
+}
diff --git a/types/config/types/subconfigs/email/smtp.rs b/types/config/types/subconfigs/email/smtp.rs
new file mode 100644
index 0000000..a02c66f
--- /dev/null
+++ b/types/config/types/subconfigs/email/smtp.rs
@@ -0,0 +1,10 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct SMTPConfiguration {
+ pub host: Option,
+ pub port: Option,
+ pub secure: bool,
+ pub username: Option,
+ pub password: Option,
+}
diff --git a/types/config/types/subconfigs/guild/autojoin.rs b/types/config/types/subconfigs/guild/autojoin.rs
new file mode 100644
index 0000000..2d88d46
--- /dev/null
+++ b/types/config/types/subconfigs/guild/autojoin.rs
@@ -0,0 +1,22 @@
+use serde::{Deserialize, Serialize};
+
+use crate::utils::Snowflake;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AutoJoinConfiguration {
+ pub enabled: bool,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub guilds: Option>,
+ pub can_leave: bool,
+}
+
+impl Default for AutoJoinConfiguration {
+ fn default() -> Self {
+ Self {
+ enabled: true,
+ guilds: None,
+ can_leave: true,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/guild/discovery.rs b/types/config/types/subconfigs/guild/discovery.rs
new file mode 100644
index 0000000..1e283b0
--- /dev/null
+++ b/types/config/types/subconfigs/guild/discovery.rs
@@ -0,0 +1,21 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct DiscoverConfiguration {
+ pub show_all_guilds: bool,
+ pub use_recommendation: bool,
+ pub offset: u16,
+ pub limit: u16,
+}
+
+impl Default for DiscoverConfiguration {
+ fn default() -> Self {
+ Self {
+ show_all_guilds: false,
+ use_recommendation: false,
+ offset: 0,
+ limit: 24,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/guild/mod.rs b/types/config/types/subconfigs/guild/mod.rs
new file mode 100644
index 0000000..e4d7dcf
--- /dev/null
+++ b/types/config/types/subconfigs/guild/mod.rs
@@ -0,0 +1,2 @@
+pub mod autojoin;
+pub mod discovery;
diff --git a/types/config/types/subconfigs/kafka/mod.rs b/types/config/types/subconfigs/kafka/mod.rs
new file mode 100644
index 0000000..1ee4015
--- /dev/null
+++ b/types/config/types/subconfigs/kafka/mod.rs
@@ -0,0 +1,7 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct KafkaBroker {
+ pub ip: String,
+ pub port: u16,
+}
diff --git a/types/config/types/subconfigs/limits/channel.rs b/types/config/types/subconfigs/limits/channel.rs
new file mode 100644
index 0000000..03e46e5
--- /dev/null
+++ b/types/config/types/subconfigs/limits/channel.rs
@@ -0,0 +1,19 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ChannelLimits {
+ pub max_pins: u16,
+ pub max_topic: u16,
+ pub max_webhooks: u16,
+}
+
+impl Default for ChannelLimits {
+ fn default() -> Self {
+ Self {
+ max_pins: 500,
+ max_topic: 1024,
+ max_webhooks: 100,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/global.rs b/types/config/types/subconfigs/limits/global.rs
new file mode 100644
index 0000000..87f9e1c
--- /dev/null
+++ b/types/config/types/subconfigs/limits/global.rs
@@ -0,0 +1,41 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct GlobalRateLimit {
+ pub limit: u16,
+ pub window: u64,
+ pub enabled: bool,
+}
+
+impl Default for GlobalRateLimit {
+ fn default() -> Self {
+ Self {
+ limit: 100,
+ window: 60 * 60 * 1000,
+ enabled: true,
+ }
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GlobalRateLimits {
+ pub register: GlobalRateLimit,
+ pub send_message: GlobalRateLimit,
+}
+
+impl Default for GlobalRateLimits {
+ fn default() -> Self {
+ Self {
+ register: GlobalRateLimit {
+ limit: 25,
+ ..Default::default()
+ },
+ send_message: GlobalRateLimit {
+ limit: 200,
+ window: 60 * 1000,
+ ..Default::default()
+ },
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/guild.rs b/types/config/types/subconfigs/limits/guild.rs
new file mode 100644
index 0000000..6def5a0
--- /dev/null
+++ b/types/config/types/subconfigs/limits/guild.rs
@@ -0,0 +1,23 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GuildLimits {
+ pub max_roles: u16,
+ pub max_emojis: u16,
+ pub max_members: u64,
+ pub max_channels: u32,
+ pub max_channels_in_category: u32,
+}
+
+impl Default for GuildLimits {
+ fn default() -> Self {
+ Self {
+ max_roles: 1000,
+ max_emojis: 20_000,
+ max_members: 25_000_000,
+ max_channels: 65_535,
+ max_channels_in_category: 65_535,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/message.rs b/types/config/types/subconfigs/limits/message.rs
new file mode 100644
index 0000000..9d368b9
--- /dev/null
+++ b/types/config/types/subconfigs/limits/message.rs
@@ -0,0 +1,26 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MessageLimits {
+ pub max_characters: u32,
+ #[serde(default)]
+ pub max_tts_characters: u32,
+ pub max_reactions: u32,
+ pub max_attachment_size: u64,
+ pub max_bulk_delete: u32,
+ pub max_embed_download_size: u64,
+}
+
+impl Default for MessageLimits {
+ fn default() -> Self {
+ Self {
+ max_characters: 1048576,
+ max_tts_characters: 160,
+ max_reactions: 2048,
+ max_attachment_size: 1024 * 1024 * 1024,
+ max_bulk_delete: 1000,
+ max_embed_download_size: 1024 * 1024 * 5,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/mod.rs b/types/config/types/subconfigs/limits/mod.rs
new file mode 100644
index 0000000..4dbc2fa
--- /dev/null
+++ b/types/config/types/subconfigs/limits/mod.rs
@@ -0,0 +1,7 @@
+pub mod channel;
+pub mod global;
+pub mod guild;
+pub mod message;
+pub mod ratelimits;
+pub mod rates;
+pub mod user;
diff --git a/types/config/types/subconfigs/limits/ratelimits/auth.rs b/types/config/types/subconfigs/limits/ratelimits/auth.rs
new file mode 100644
index 0000000..3bfdccc
--- /dev/null
+++ b/types/config/types/subconfigs/limits/ratelimits/auth.rs
@@ -0,0 +1,28 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::limits::ratelimits::RateLimitOptions;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct AuthRateLimit {
+ pub login: RateLimitOptions,
+ pub register: RateLimitOptions,
+}
+
+impl Default for AuthRateLimit {
+ fn default() -> Self {
+ Self {
+ login: RateLimitOptions {
+ bot: None,
+ count: 5,
+ window: 60,
+ only_ip: false,
+ },
+ register: RateLimitOptions {
+ bot: None,
+ count: 2,
+ window: 60 * 60 * 12,
+ only_ip: false,
+ },
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/ratelimits/mod.rs b/types/config/types/subconfigs/limits/ratelimits/mod.rs
new file mode 100644
index 0000000..66a2b78
--- /dev/null
+++ b/types/config/types/subconfigs/limits/ratelimits/mod.rs
@@ -0,0 +1,14 @@
+use serde::{Deserialize, Serialize};
+
+pub mod auth;
+pub mod route;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct RateLimitOptions {
+ pub bot: Option,
+ pub count: u64,
+ pub window: u64,
+ #[serde(default)]
+ pub only_ip: bool,
+}
diff --git a/types/config/types/subconfigs/limits/ratelimits/route.rs b/types/config/types/subconfigs/limits/ratelimits/route.rs
new file mode 100644
index 0000000..04e5a42
--- /dev/null
+++ b/types/config/types/subconfigs/limits/ratelimits/route.rs
@@ -0,0 +1,37 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::limits::ratelimits::{auth::AuthRateLimit, RateLimitOptions};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RouteRateLimit {
+ pub guild: RateLimitOptions,
+ pub webhook: RateLimitOptions,
+ pub channel: RateLimitOptions,
+ pub auth: AuthRateLimit,
+}
+
+impl Default for RouteRateLimit {
+ fn default() -> Self {
+ Self {
+ guild: RateLimitOptions {
+ bot: None,
+ count: 5,
+ window: 5,
+ only_ip: false,
+ },
+ webhook: RateLimitOptions {
+ bot: None,
+ count: 10,
+ window: 5,
+ only_ip: false,
+ },
+ channel: RateLimitOptions {
+ bot: None,
+ count: 10,
+ window: 5,
+ only_ip: false,
+ },
+ auth: AuthRateLimit::default(),
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/rates.rs b/types/config/types/subconfigs/limits/rates.rs
new file mode 100644
index 0000000..3185b37
--- /dev/null
+++ b/types/config/types/subconfigs/limits/rates.rs
@@ -0,0 +1,41 @@
+use serde::{Deserialize, Serialize};
+
+use crate::config::types::subconfigs::limits::ratelimits::{
+ route::RouteRateLimit, RateLimitOptions,
+};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RateLimits {
+ pub enabled: bool,
+ pub ip: RateLimitOptions,
+ pub global: RateLimitOptions,
+ pub error: RateLimitOptions,
+ pub routes: RouteRateLimit,
+}
+
+impl Default for RateLimits {
+ fn default() -> Self {
+ Self {
+ enabled: false,
+ ip: RateLimitOptions {
+ bot: None,
+ count: 500,
+ window: 5,
+ only_ip: false,
+ },
+ global: RateLimitOptions {
+ bot: None,
+ count: 250,
+ window: 5,
+ only_ip: false,
+ },
+ error: RateLimitOptions {
+ bot: None,
+ count: 10,
+ window: 5,
+ only_ip: false,
+ },
+ routes: RouteRateLimit::default(),
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/limits/user.rs b/types/config/types/subconfigs/limits/user.rs
new file mode 100644
index 0000000..e43b746
--- /dev/null
+++ b/types/config/types/subconfigs/limits/user.rs
@@ -0,0 +1,19 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct UserLimits {
+ pub max_guilds: u64,
+ pub max_username: u16,
+ pub max_friends: u64,
+}
+
+impl Default for UserLimits {
+ fn default() -> Self {
+ Self {
+ max_guilds: 1048576,
+ max_username: 32,
+ max_friends: 5000,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/mod.rs b/types/config/types/subconfigs/mod.rs
new file mode 100644
index 0000000..4c85096
--- /dev/null
+++ b/types/config/types/subconfigs/mod.rs
@@ -0,0 +1,9 @@
+pub mod client;
+pub mod defaults;
+pub mod email;
+pub mod guild;
+pub mod kafka;
+pub mod limits;
+pub mod region;
+pub mod register;
+pub mod security;
diff --git a/types/config/types/subconfigs/region/mod.rs b/types/config/types/subconfigs/region/mod.rs
new file mode 100644
index 0000000..e0b1800
--- /dev/null
+++ b/types/config/types/subconfigs/region/mod.rs
@@ -0,0 +1,21 @@
+use serde::{Deserialize, Serialize};
+
+
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct LatLong {
+ pub latitude: f64,
+ pub longitude: f64,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct Region {
+ pub id: String,
+ pub name: String,
+ pub endpoint: String,
+ pub location: Option,
+ pub vip: bool,
+ pub custom: bool,
+ #[serde(default)]
+ pub deprecated: bool,
+}
diff --git a/types/config/types/subconfigs/register/date_of_birth.rs b/types/config/types/subconfigs/register/date_of_birth.rs
new file mode 100644
index 0000000..9c1bec1
--- /dev/null
+++ b/types/config/types/subconfigs/register/date_of_birth.rs
@@ -0,0 +1,16 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct DateOfBirthConfiguration {
+ pub required: bool,
+ pub minimum: u8,
+}
+
+impl Default for DateOfBirthConfiguration {
+ fn default() -> Self {
+ Self {
+ required: true,
+ minimum: 13,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/register/email.rs b/types/config/types/subconfigs/register/email.rs
new file mode 100644
index 0000000..ac99bfc
--- /dev/null
+++ b/types/config/types/subconfigs/register/email.rs
@@ -0,0 +1,21 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RegistrationEmailConfiguration {
+ pub required: bool,
+ pub allowlist: bool,
+ #[serde(default)]
+ pub blacklist: bool,
+ #[serde(default)]
+ pub domains: Vec,
+}
+impl Default for RegistrationEmailConfiguration {
+ fn default() -> Self {
+ Self {
+ required: false,
+ allowlist: false,
+ blacklist: true,
+ domains: Vec::new(),
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/register/mod.rs b/types/config/types/subconfigs/register/mod.rs
new file mode 100644
index 0000000..ad92571
--- /dev/null
+++ b/types/config/types/subconfigs/register/mod.rs
@@ -0,0 +1,7 @@
+mod date_of_birth;
+mod email;
+mod password;
+
+pub use date_of_birth::DateOfBirthConfiguration;
+pub use email::RegistrationEmailConfiguration;
+pub use password::PasswordConfiguration;
diff --git a/types/config/types/subconfigs/register/password.rs b/types/config/types/subconfigs/register/password.rs
new file mode 100644
index 0000000..9247f7d
--- /dev/null
+++ b/types/config/types/subconfigs/register/password.rs
@@ -0,0 +1,23 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct PasswordConfiguration {
+ pub required: bool,
+ pub min_length: u8,
+ pub min_numbers: u8,
+ pub min_upper_case: u8,
+ pub min_symbols: u8,
+}
+
+impl Default for PasswordConfiguration {
+ fn default() -> Self {
+ Self {
+ required: false,
+ min_length: 8,
+ min_numbers: 2,
+ min_upper_case: 2,
+ min_symbols: 0,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/security/captcha.rs b/types/config/types/subconfigs/security/captcha.rs
new file mode 100644
index 0000000..82bb517
--- /dev/null
+++ b/types/config/types/subconfigs/security/captcha.rs
@@ -0,0 +1,27 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum CaptchaService {
+ Recaptcha,
+ HCaptcha,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct CaptchaConfiguration {
+ pub enabled: bool,
+ pub service: CaptchaService,
+ pub sitekey: Option,
+ pub secret: Option,
+}
+
+impl Default for CaptchaConfiguration {
+ fn default() -> Self {
+ Self {
+ enabled: false,
+ service: CaptchaService::HCaptcha,
+ sitekey: None,
+ secret: None,
+ }
+ }
+}
diff --git a/types/config/types/subconfigs/security/mod.rs b/types/config/types/subconfigs/security/mod.rs
new file mode 100644
index 0000000..ceeb0d3
--- /dev/null
+++ b/types/config/types/subconfigs/security/mod.rs
@@ -0,0 +1,5 @@
+mod captcha;
+mod twofactor;
+
+pub use captcha::{CaptchaConfiguration, CaptchaService};
+pub use twofactor::TwoFactorConfiguration;
diff --git a/types/config/types/subconfigs/security/twofactor.rs b/types/config/types/subconfigs/security/twofactor.rs
new file mode 100644
index 0000000..39a0373
--- /dev/null
+++ b/types/config/types/subconfigs/security/twofactor.rs
@@ -0,0 +1,15 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct TwoFactorConfiguration {
+ pub generate_backup_codes: bool,
+}
+
+impl Default for TwoFactorConfiguration {
+ fn default() -> Self {
+ Self {
+ generate_backup_codes: true,
+ }
+ }
+}
diff --git a/types/config/types/template_configuration.rs b/types/config/types/template_configuration.rs
new file mode 100644
index 0000000..932670e
--- /dev/null
+++ b/types/config/types/template_configuration.rs
@@ -0,0 +1,21 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct TemplateConfiguration {
+ pub enabled: bool,
+ pub allow_template_creation: bool,
+ pub allow_discord_templates: bool,
+ pub allow_raws: bool,
+}
+
+impl Default for TemplateConfiguration {
+ fn default() -> Self {
+ Self {
+ enabled: true,
+ allow_template_creation: true,
+ allow_discord_templates: true,
+ allow_raws: true,
+ }
+ }
+}
diff --git a/types/entities/application.rs b/types/entities/application.rs
new file mode 100644
index 0000000..b838a5b
--- /dev/null
+++ b/types/entities/application.rs
@@ -0,0 +1,140 @@
+
+
+use crate::utils::Snowflake;
+use bitflags::{bitflags, Flags};
+use serde::{Deserialize, Serialize};
+use serde_json::Value;
+#[cfg(feature = "sqlx")]
+use sqlx::FromRow;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "sqlx", derive(FromRow))]
+pub struct Application {
+ pub id: Snowflake,
+ pub name: String,
+ pub icon: Option,
+ pub description: Option,
+ pub summary: Option,
+ #[cfg(feature = "sqlx")]
+ pub r#type: Option>,
+ #[cfg(not(feature = "sqlx"))]
+ pub r#type: Option,
+ pub hook: bool,
+ pub bot_public: bool,
+ pub bot_require_code_grant: bool,
+ pub verify_key: String,
+ pub owner_id: Snowflake,
+ pub flags: u64,
+ #[cfg(feature = "sqlx")]
+ pub redirect_uris: Option>>,
+ #[cfg(not(feature = "sqlx"))]
+ pub redirect_uris: Option>,
+ pub rpc_application_state: i64,
+ pub store_application_state: i64,
+ pub verification_state: i64,
+ pub interactions_endpoint_url: Option,
+ pub integration_public: bool,
+ pub integration_require_code_grant: bool,
+ pub discoverability_state: i64,
+ pub discovery_eligibility_flags: i64,
+ pub bot_user_id: Snowflake,
+ #[cfg(feature = "sqlx")]
+ pub tags: Option>>,
+ #[cfg(not(feature = "sqlx"))]
+ pub tags: Option>,
+ pub cover_image: Option,
+ #[cfg(feature = "sqlx")]
+ pub install_params: Option>,
+ #[cfg(not(feature = "sqlx"))]
+ pub install_params: Option,
+ pub terms_of_service_url: Option,
+ pub privacy_policy_url: Option,
+ pub team_id: Option,
+}
+
+impl Application {
+ pub fn flags(&self) -> ApplicationFlags {
+ ApplicationFlags::from_bits(self.flags.to_owned()).unwrap()
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct InstallParams {
+ pub scopes: Vec,
+ pub permissions: String,
+}
+
+bitflags! {
+ #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
+ pub struct ApplicationFlags: u64 {
+ const APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 1 << 6;
+ const GATEWAY_PRESENCE = 1 << 12;
+ const GATEWAY_PRESENCE_LIMITED = 1 << 13;
+ const GATEWAY_GUILD_MEMBERS = 1 << 14;
+ const GATEWAY_GUILD_MEMBERS_LIMITED = 1 << 15;
+ const VERIFICATION_PENDING_GUILD_LIMIT = 1 << 16;
+ const EMBEDDED = 1 << 17;
+ const GATEWAY_MESSAGE_CONTENT = 1 << 18;
+ const GATEWAY_MESSAGE_CONTENT_LIMITED = 1 << 19;
+ const APPLICATION_COMMAND_BADGE = 1 << 23;
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct ApplicationCommand {
+ pub id: Snowflake,
+ pub application_id: Snowflake,
+ pub name: String,
+ pub description: String,
+ pub options: Vec,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct ApplicationCommandOption {
+ pub r#type: ApplicationCommandOptionType,
+ pub name: String,
+ pub description: String,
+ pub required: bool,
+ pub choices: Vec,
+ pub options: Vec,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct ApplicationCommandOptionChoice {
+ pub name: String,
+ pub value: Value,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
+pub enum ApplicationCommandOptionType {
+ #[serde(rename = "SUB_COMMAND")]
+ SubCommand = 1,
+ #[serde(rename = "SUB_COMMAND_GROUP")]
+ SubCommandGroup = 2,
+ #[serde(rename = "STRING")]
+ String = 3,
+ #[serde(rename = "INTEGER")]
+ Integer = 4,
+ #[serde(rename = "BOOLEAN")]
+ Boolean = 5,
+ #[serde(rename = "USER")]
+ User = 6,
+ #[serde(rename = "CHANNEL")]
+ Channel = 7,
+ #[serde(rename = "ROLE")]
+ Role = 8,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct ApplicationCommandInteractionData {
+ pub id: Snowflake,
+ pub name: String,
+ pub options: Vec,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct ApplicationCommandInteractionDataOption {
+ pub name: String,
+ pub value: Value,
+ pub options: Vec,
+}
diff --git a/types/entities/attachment.rs b/types/entities/attachment.rs
new file mode 100644
index 0000000..56384f7
--- /dev/null
+++ b/types/entities/attachment.rs
@@ -0,0 +1,113 @@
+use serde::{Deserialize, Serialize};
+
+use crate::utils::Snowflake;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct Attachment {
+ pub id: Snowflake,
+ pub filename: String,
+ pub description: Option,
+ pub content_type: Option,
+ pub size: u64,
+ pub url: String,
+ pub proxy_url: String,
+ pub height: Option,
+ pub width: Option,
+ pub message_id: Snowflake,
+ pub ephemeral: Option,
+ pub duration_secs: Option,
+ pub waveform: Option,
+ #[serde(skip_serializing)]
+ pub content: Vec,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+
+pub struct PartialDiscordFileAttachment {
+ pub id: Option,
+ pub filename: String,
+ pub description: Option,
+ pub content_type: Option,
+ pub size: Option,
+ pub url: Option,
+ pub proxy_url: Option,
+ pub height: Option,
+ pub width: Option,
+ pub ephemeral: Option,
+ pub duration_secs: Option,
+ pub waveform: Option,
+ #[serde(skip_serializing)]
+ pub content: Vec,
+}
+
+impl PartialDiscordFileAttachment {
+ /**
+ Moves `self.content` out of `self` and returns it.
+ # Returns
+ Vec
+ */
+ pub fn move_content(self) -> (Vec, PartialDiscordFileAttachment) {
+ let content = self.content;
+ let updated_struct = PartialDiscordFileAttachment {
+ id: self.id,
+ filename: self.filename,
+ description: self.description,
+ content_type: self.content_type,
+ size: self.size,
+ url: self.url,
+ proxy_url: self.proxy_url,
+ height: self.height,
+ width: self.width,
+ ephemeral: self.ephemeral,
+ duration_secs: self.duration_secs,
+ waveform: self.waveform,
+ content: Vec::new(),
+ };
+ (content, updated_struct)
+ }
+
+ pub fn move_filename(self) -> (String, PartialDiscordFileAttachment) {
+ let filename = self.filename;
+ let updated_struct = PartialDiscordFileAttachment {
+ id: self.id,
+ filename: String::new(),
+ description: self.description,
+ content_type: self.content_type,
+ size: self.size,
+ url: self.url,
+ proxy_url: self.proxy_url,
+ height: self.height,
+ width: self.width,
+
+ ephemeral: self.ephemeral,
+ duration_secs: self.duration_secs,
+ waveform: self.waveform,
+ content: self.content,
+ };
+ (filename, updated_struct)
+ }
+
+ pub fn move_content_type(self) -> (Option, PartialDiscordFileAttachment) {
+ let content_type = self.content_type;
+ let updated_struct = PartialDiscordFileAttachment {
+ id: self.id,
+ filename: self.filename,
+ description: self.description,
+ content_type: None,
+ size: self.size,
+ url: self.url,
+ proxy_url: self.proxy_url,
+ height: self.height,
+ width: self.width,
+ ephemeral: self.ephemeral,
+ duration_secs: self.duration_secs,
+ waveform: self.waveform,
+ content: self.content,
+ };
+ (content_type, updated_struct)
+ }
+
+ pub fn set_id(&mut self, id: i16) {
+ self.id = Some(id);
+ }
+}
diff --git a/types/entities/channel.rs b/types/entities/channel.rs
new file mode 100644
index 0000000..71c65a1
--- /dev/null
+++ b/types/entities/channel.rs
@@ -0,0 +1,116 @@
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ entities::{GuildMember, User},
+ utils::Snowflake,
+};
+
+#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
+pub struct Channel {
+ pub id: Snowflake,
+ #[serde(rename = "type")]
+ pub channel_type: ChannelType,
+ pub guild_id: Option,
+ pub position: Option,
+ pub permission_overwrites: Option>,
+ pub name: Option,
+ pub topic: Option,
+ pub nsfw: Option,
+ pub last_message_id: Option,
+ pub bitrate: Option,
+ pub user_limit: Option,
+ pub rate_limit_per_user: Option,
+ pub recipients: Option>,
+ pub icon: Option,
+ pub owner_id: Option,
+ pub application_id: Option,
+ pub parent_id: Option,
+ pub last_pin_timestamp: Option,
+ pub rtc_region: Option,
+ pub video_quality_mode: Option,
+ pub message_count: Option,
+ pub member_count: Option,
+ pub thread_metadata: Option,
+ pub member: Option,
+ pub default_auto_archive_duration: Option,
+ pub permissions: Option,
+ pub flags: Option,
+ pub total_message_sent: Option,
+ pub available_tags: Option>,
+ pub applied_tags: Option>,
+ pub default_reaction_emoji: Option,
+ pub default_thread_rate_limit_per_user: Option,
+ pub default_sort_order: Option,
+ pub default_forum_layout: Option,
+}
+
+#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
+pub struct Tag {
+ pub id: u64,
+ pub name: String,
+ pub moderated: bool,
+ pub emoji_id: Option,
+ pub emoji_name: Option,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
+pub struct PermissionOverwrite {
+ pub id: String,
+ #[serde(rename = "type")]
+ pub overwrite_type: u8,
+ pub allow: String,
+ pub deny: String,
+}
+
+#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
+pub struct ThreadMetadata {
+ pub archived: bool,
+ pub auto_archive_duration: i32,
+ pub archive_timestamp: String,
+ pub locked: bool,
+ pub invitable: Option,
+ pub create_timestamp: Option,
+}
+
+#[derive(Default, Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
+pub struct ThreadMember {
+ pub id: Option,
+ pub user_id: Option,
+ pub join_timestamp: Option,
+ pub flags: Option,
+ pub member: Option,
+}
+
+#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
+pub struct DefaultReaction {
+ pub emoji_id: Option,
+ pub emoji_name: Option,
+}
+
+#[derive(Default, Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
+#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
+#[repr(i32)]
+pub enum ChannelType {
+ #[default]
+ GuildText = 0,
+ Dm = 1,
+ GuildVoice = 2,
+ GroupDm = 3,
+ GuildCategory = 4,
+ GuildNews = 5,
+ GuildStore = 6,
+ Encrypted = 7,
+ EncryptedThreads = 8,
+ Transactional = 9,
+ GuildNewsThread = 10,
+ GuildPublicThread = 11,
+ GuildPrivateThread = 12,
+ GuildStageVoice = 13,
+ Directory = 14,
+ GuildForum = 15,
+ TicketTracker = 33,
+ Kanban = 34,
+ VoicelessWhiteboard = 35,
+ CustomStart = 64,
+ Unhandled = 255,
+}
diff --git a/types/entities/config.rs b/types/entities/config.rs
new file mode 100644
index 0000000..25b1ef1
--- /dev/null
+++ b/types/entities/config.rs
@@ -0,0 +1,34 @@
+use serde::{Deserialize, Serialize};
+use serde_json::Value;
+#[cfg(feature = "sqlx")]
+use sqlx::FromRow;
+
+#[derive(Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "sqlx", derive(FromRow))]
+pub struct ConfigEntity {
+ pub key: String,
+ pub value: Option,
+}
+
+impl ConfigEntity {
+ pub fn as_string(&self) -> Option {
+ let Some(v) = self.value.as_ref() else {
+ return None;
+ };
+ Some(v.as_str().expect("value is not a string").to_string())
+ }
+
+ pub fn as_bool(&self) -> Option {
+ let Some(v) = self.value.as_ref() else {
+ return None;
+ };
+ Some(v.as_bool().expect("value is not a boolean"))
+ }
+
+ pub fn as_int(&self) -> Option {
+ let Some(v) = self.value.as_ref() else {
+ return None;
+ };
+ Some(v.as_i64().expect("value is not a number"))
+ }
+}
diff --git a/types/entities/emoji.rs b/types/entities/emoji.rs
new file mode 100644
index 0000000..2698607
--- /dev/null
+++ b/types/entities/emoji.rs
@@ -0,0 +1,15 @@
+use serde::{Deserialize, Serialize};
+
+use crate::entities::User;
+
+#[derive(Debug, Deserialize, Serialize, Default, Clone)]
+pub struct Emoji {
+ pub id: Option,
+ pub name: Option,
+ pub roles: Option>,
+ pub user: Option,
+ pub require_colons: Option,
+ pub managed: Option,
+ pub animated: Option,
+ pub available: Option,
+}
diff --git a/types/entities/guild.rs b/types/entities/guild.rs
new file mode 100644
index 0000000..9b2abe7
--- /dev/null
+++ b/types/entities/guild.rs
@@ -0,0 +1,117 @@
+use chrono::{DateTime, Utc};
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ entities::{Channel, Emoji, GuildTemplate, RoleObject, Sticker, User, VoiceState, Webhook},
+ interfaces::WelcomeScreenObject,
+ utils::Snowflake,
+};
+
+/// See https://discord.com/developers/docs/resources/guild
+#[derive(Serialize, Deserialize, Debug, Default, Clone)]
+pub struct Guild {
+ pub id: Snowflake,
+ pub name: String,
+ pub icon: Option,
+ pub icon_hash: Option,
+ pub splash: Option,
+ pub discovery_splash: Option,
+ pub owner: Option,
+ pub owner_id: Option,
+ pub permissions: Option,
+ pub afk_channel_id: Option,
+ pub afk_timeout: Option,
+ pub widget_enabled: Option,
+ pub widget_channel_id: Option,
+ pub widget_channel: Option,
+ pub verification_level: Option,
+ pub default_message_notifications: Option,
+ pub explicit_content_filter: Option,
+ pub roles: Vec,
+ pub emojis: Vec,
+ pub features: Vec,
+ pub application_id: Option,
+ pub system_channel_id: Option,
+ pub system_channel_flags: Option,
+ pub rules_channel_id: Option,
+ pub rules_channel: Option,
+ pub max_presences: Option,
+ pub max_members: Option,
+ pub vanity_url_code: Option,
+ pub description: Option,
+ pub banner: Option,
+ pub premium_tier: Option,
+ pub premium_subscription_count: Option,
+ pub preferred_locale: Option,
+ pub public_updates_channel_id: Option,
+ pub public_updates_channel: Option,
+ pub max_video_channel_users: Option,
+ pub max_stage_video_channel_users: Option,
+ pub approximate_member_count: Option,
+ pub approximate_presence_count: Option,
+ pub member_count: Option,
+ pub presence_count: Option,
+ pub welcome_screen: Option,
+ pub nsfw_level: u8,
+ pub nsfw: bool,
+ pub stickers: Option>,
+ pub premium_progress_bar_enabled: Option,
+ pub joined_at: String,
+ pub afk_channel: Option,
+ pub bans: Option>,
+ pub primary_category_id: Option,
+ pub large: Option,
+ pub channels: Option>,
+ pub template_id: Option,
+ pub template: Option,
+ pub invites: Option>,
+ pub voice_states: Option>,
+ pub webhooks: Option>,
+ pub mfa_level: Option,
+ pub region: Option,
+ pub unavailable: bool,
+ pub parent: Option,
+}
+
+/// See https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user-
+#[derive(Serialize, Deserialize, Debug, Default, Clone)]
+pub struct GuildBan {
+ pub id: Snowflake,
+ pub user_id: Snowflake,
+ pub guild_id: Snowflake,
+ pub executor_id: Snowflake,
+ pub reason: Option,
+}
+
+/// See https://docs.spacebar.chat/routes/#cmp--schemas-invite
+#[derive(Serialize, Deserialize, Debug, Default, Clone)]
+pub struct GuildInvite {
+ pub code: String,
+ pub temporary: Option,
+ pub uses: Option,
+ pub max_uses: Option,
+ pub max_age: Option,
+ pub created_at: DateTime,
+ pub expires_at: Option>,
+ pub guild_id: String,
+ pub guild: Option,
+ pub channel_id: String,
+ pub channel: Option,
+ pub inviter_id: Option,
+ pub inviter: Option,
+ pub target_user_id: Option,
+ pub target_user: Option,
+ pub target_user_type: Option,
+ pub vanity_url: Option,
+}
+
+#[derive(Serialize, Deserialize, Debug, Default)]
+pub struct UnavailableGuild {
+ id: String,
+ unavailable: bool,
+}
+
+#[derive(Serialize, Deserialize, Debug, Default, Clone)]
+pub struct GuildCreateResponse {
+ pub id: String,
+}
diff --git a/types/entities/guild_member.rs b/types/entities/guild_member.rs
new file mode 100644
index 0000000..272baa7
--- /dev/null
+++ b/types/entities/guild_member.rs
@@ -0,0 +1,19 @@
+use serde::{Deserialize, Serialize};
+
+use crate::entities::User;
+
+#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
+pub struct GuildMember {
+ pub user: Option,
+ pub nick: Option,
+ pub avatar: Option,
+ pub roles: Vec,
+ pub joined_at: String,
+ pub premium_since: Option,
+ pub deaf: bool,
+ pub mute: bool,
+ pub flags: i32,
+ pub pending: Option,
+ pub permissions: Option,
+ pub communication_disabled_until: Option,
+}
diff --git a/types/entities/integration.rs b/types/entities/integration.rs
new file mode 100644
index 0000000..95b0de6
--- /dev/null
+++ b/types/entities/integration.rs
@@ -0,0 +1,36 @@
+use chrono::{DateTime, Utc};
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ entities::{Application, User},
+ utils::Snowflake,
+};
+
+#[derive(Default, Debug, Deserialize, Serialize, Clone)]
+/// See https://discord.com/developers/docs/resources/guild#integration-object-integration-structure
+pub struct Integration {
+ pub id: Snowflake,
+ pub name: String,
+ #[serde(rename = "type")]
+ pub integration_type: String,
+ pub enabled: bool,
+ pub syncing: Option,
+ pub role_id: Option,
+ pub enabled_emoticons: Option,
+ pub expire_behaviour: Option,
+ pub expire_grace_period: Option,
+ pub user: Option,
+ pub account: IntegrationAccount,
+ pub synced_at: Option>,
+ pub subscriber_count: Option,
+ pub revoked: Option,
+ pub application: Option,
+ pub scopes: Option>,
+}
+
+#[derive(Default, Debug, Deserialize, Serialize, Clone)]
+/// See https://discord.com/developers/docs/resources/guild#integration-account-object-integration-account-structure
+pub struct IntegrationAccount {
+ pub id: String,
+ pub name: String,
+}
diff --git a/types/entities/message.rs b/types/entities/message.rs
new file mode 100644
index 0000000..914affa
--- /dev/null
+++ b/types/entities/message.rs
@@ -0,0 +1,185 @@
+use serde::{Deserialize, Serialize};
+
+use crate::{
+ entities::{
+ Application, Attachment, Channel, Emoji, GuildMember, RoleSubscriptionData, Sticker,
+ StickerItem, User,
+ },
+ utils::Snowflake,
+};
+
+#[derive(Debug, Serialize, Deserialize, Default)]
+pub struct Message {
+ id: Snowflake,
+ pub channel_id: Snowflake,
+ author: User,
+ content: String,
+ timestamp: String,
+ edited_timestamp: Option,
+ tts: bool,
+ mention_everyone: bool,
+ mentions: Vec,
+ mention_roles: Vec,
+ mention_channels: Option>,
+ pub attachments: Vec,
+ embeds: Vec