summary refs log tree commit diff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/util/config/Config.ts46
-rw-r--r--src/util/config/index.ts2
-rw-r--r--src/util/config/types/ApiConfiguration.ts5
-rw-r--r--src/util/config/types/ClientConfiguration.ts8
-rw-r--r--src/util/config/types/DefaultsConfiguration.ts6
-rw-r--r--src/util/config/types/EndpointConfiguration.ts4
-rw-r--r--src/util/config/types/GeneralConfiguration.ts12
-rw-r--r--src/util/config/types/GifConfiguration.ts5
-rw-r--r--src/util/config/types/GuildConfiguration.ts6
-rw-r--r--src/util/config/types/KafkaConfiguration.ts5
-rw-r--r--src/util/config/types/LimitConfigurations.ts9
-rw-r--r--src/util/config/types/LoginConfiguration.ts3
-rw-r--r--src/util/config/types/MetricsConfiguration.ts3
-rw-r--r--src/util/config/types/RabbitMQConfiguration.ts3
-rw-r--r--src/util/config/types/RegionConfiguration.ts16
-rw-r--r--src/util/config/types/RegisterConfiguration.ts19
-rw-r--r--src/util/config/types/SecurityConfiguration.ts19
-rw-r--r--src/util/config/types/SentryConfiguration.ts8
-rw-r--r--src/util/config/types/TemplateConfiguration.ts6
-rw-r--r--src/util/config/types/index.ts18
-rw-r--r--src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts4
-rw-r--r--src/util/config/types/subconfigurations/client/index.ts1
-rw-r--r--src/util/config/types/subconfigurations/defaults/GuildDefaults.ts8
-rw-r--r--src/util/config/types/subconfigurations/defaults/UserDefaults.ts5
-rw-r--r--src/util/config/types/subconfigurations/defaults/index.ts2
-rw-r--r--src/util/config/types/subconfigurations/guild/AutoJoin.ts5
-rw-r--r--src/util/config/types/subconfigurations/guild/Discovery.ts6
-rw-r--r--src/util/config/types/subconfigurations/guild/index.ts2
-rw-r--r--src/util/config/types/subconfigurations/index.ts8
-rw-r--r--src/util/config/types/subconfigurations/kafka/KafkaBroker.ts4
-rw-r--r--src/util/config/types/subconfigurations/kafka/index.ts1
-rw-r--r--src/util/config/types/subconfigurations/limits/ChannelLimits.ts5
-rw-r--r--src/util/config/types/subconfigurations/limits/GuildLimits.ts8
-rw-r--r--src/util/config/types/subconfigurations/limits/MessageLimits.ts8
-rw-r--r--src/util/config/types/subconfigurations/limits/RateLimits.ts18
-rw-r--r--src/util/config/types/subconfigurations/limits/UserLimits.ts5
-rw-r--r--src/util/config/types/subconfigurations/limits/index.ts6
-rw-r--r--src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts12
-rw-r--r--src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts6
-rw-r--r--src/util/config/types/subconfigurations/limits/ratelimits/Route.ts19
-rw-r--r--src/util/config/types/subconfigurations/limits/ratelimits/index.ts3
-rw-r--r--src/util/config/types/subconfigurations/region/Region.ts12
-rw-r--r--src/util/config/types/subconfigurations/region/index.ts1
-rw-r--r--src/util/config/types/subconfigurations/register/DateOfBirth.ts4
-rw-r--r--src/util/config/types/subconfigurations/register/Email.ts7
-rw-r--r--src/util/config/types/subconfigurations/register/Password.ts7
-rw-r--r--src/util/config/types/subconfigurations/register/index.ts3
-rw-r--r--src/util/config/types/subconfigurations/security/Captcha.ts6
-rw-r--r--src/util/config/types/subconfigurations/security/TwoFactor.ts3
-rw-r--r--src/util/config/types/subconfigurations/security/index.ts2
-rw-r--r--src/util/dtos/DmChannelDTO.ts (renamed from util/src/dtos/DmChannelDTO.ts)4
-rw-r--r--src/util/dtos/UserDTO.ts (renamed from util/src/dtos/UserDTO.ts)0
-rw-r--r--src/util/dtos/index.ts (renamed from util/src/dtos/index.ts)0
-rw-r--r--src/util/entities/Application.ts (renamed from util/src/entities/Application.ts)101
-rw-r--r--src/util/entities/Attachment.ts (renamed from util/src/entities/Attachment.ts)2
-rw-r--r--src/util/entities/AuditLog.ts (renamed from util/src/entities/AuditLog.ts)18
-rw-r--r--src/util/entities/BackupCodes.ts19
-rw-r--r--src/util/entities/Ban.ts (renamed from util/src/entities/Ban.ts)4
-rw-r--r--src/util/entities/BaseClass.ts26
-rw-r--r--src/util/entities/Categories.ts (renamed from util/src/entities/Categories.ts)24
-rw-r--r--src/util/entities/Channel.ts (renamed from util/src/entities/Channel.ts)769
-rw-r--r--src/util/entities/ClientRelease.ts (renamed from util/src/entities/ClientRelease.ts)2
-rw-r--r--src/util/entities/Config.ts11
-rw-r--r--src/util/entities/ConnectedAccount.ts (renamed from util/src/entities/ConnectedAccount.ts)2
-rw-r--r--src/util/entities/Emoji.ts (renamed from util/src/entities/Emoji.ts)5
-rw-r--r--src/util/entities/Encryption.ts25
-rw-r--r--src/util/entities/Group.ts (renamed from util/src/entities/Group.ts)8
-rw-r--r--src/util/entities/Guild.ts (renamed from util/src/entities/Guild.ts)80
-rw-r--r--src/util/entities/Invite.ts (renamed from util/src/entities/Invite.ts)25
-rw-r--r--src/util/entities/Member.ts (renamed from util/src/entities/Member.ts)150
-rw-r--r--src/util/entities/Message.ts (renamed from util/src/entities/Message.ts)42
-rw-r--r--src/util/entities/Migration.ts (renamed from util/src/entities/Migration.ts)4
-rw-r--r--src/util/entities/Note.ts18
-rw-r--r--src/util/entities/RateLimit.ts (renamed from util/src/entities/RateLimit.ts)0
-rw-r--r--src/util/entities/ReadState.ts (renamed from util/src/entities/ReadState.ts)9
-rw-r--r--src/util/entities/Recipient.ts (renamed from util/src/entities/Recipient.ts)4
-rw-r--r--src/util/entities/Relationship.ts (renamed from util/src/entities/Relationship.ts)8
-rw-r--r--src/util/entities/Role.ts (renamed from util/src/entities/Role.ts)2
-rw-r--r--src/util/entities/Session.ts (renamed from util/src/entities/Session.ts)16
-rw-r--r--src/util/entities/Sticker.ts (renamed from util/src/entities/Sticker.ts)12
-rw-r--r--src/util/entities/StickerPack.ts (renamed from util/src/entities/StickerPack.ts)4
-rw-r--r--src/util/entities/Team.ts (renamed from util/src/entities/Team.ts)4
-rw-r--r--src/util/entities/TeamMember.ts (renamed from util/src/entities/TeamMember.ts)6
-rw-r--r--src/util/entities/Template.ts (renamed from util/src/entities/Template.ts)0
-rw-r--r--src/util/entities/User.ts (renamed from util/src/entities/User.ts)224
-rw-r--r--src/util/entities/UserGroup.ts (renamed from util/src/entities/UserGroup.ts)14
-rw-r--r--src/util/entities/UserSettings.ts119
-rw-r--r--src/util/entities/VoiceState.ts (renamed from util/src/entities/VoiceState.ts)8
-rw-r--r--src/util/entities/Webhook.ts (renamed from util/src/entities/Webhook.ts)12
-rw-r--r--src/util/entities/index.ts (renamed from util/src/entities/index.ts)5
-rw-r--r--src/util/index.ts (renamed from util/src/index.ts)9
-rw-r--r--src/util/interfaces/Activity.ts (renamed from util/src/interfaces/Activity.ts)2
-rw-r--r--src/util/interfaces/Event.ts (renamed from util/src/interfaces/Event.ts)22
-rw-r--r--src/util/interfaces/Interaction.ts (renamed from util/src/interfaces/Interaction.ts)4
-rw-r--r--src/util/interfaces/Presence.ts (renamed from util/src/interfaces/Presence.ts)4
-rw-r--r--src/util/interfaces/Status.ts (renamed from util/src/interfaces/Status.ts)0
-rw-r--r--src/util/interfaces/index.ts (renamed from util/src/interfaces/index.ts)4
-rw-r--r--src/util/migrations/mariadb/1659901151025-initial.ts1218
-rw-r--r--src/util/migrations/mariadb/1659921859145-premium_since_as_date.ts25
-rw-r--r--src/util/migrations/mariadb/1660130586602-updated-applications.ts184
-rw-r--r--src/util/migrations/mariadb/1661273147273-test.ts149
-rw-r--r--src/util/migrations/mariadb/1661273179287-test2.ts18
-rw-r--r--src/util/migrations/postgres/1659899687168-initial.ts1244
-rw-r--r--src/util/migrations/postgres/1659921826567-premium_since_as_date.ts25
-rw-r--r--src/util/migrations/postgres/1660130561959-updated-applications.ts181
-rw-r--r--src/util/migrations/postgres/1660257815436-CodeCleanup2.ts58
-rw-r--r--src/util/migrations/postgres/1660258372154-CodeCleanup3.ts18
-rw-r--r--src/util/migrations/postgres/1660260565996-CodeCleanup4.ts32
-rw-r--r--src/util/migrations/postgres/1660265907544-CodeCleanup5.ts25
-rw-r--r--src/util/migrations/postgres/1660416055566-InvitersAreDeletable.ts25
-rw-r--r--src/util/migrations/postgres/1660549242936-fix_nullables.ts29
-rw-r--r--src/util/migrations/sqlite/1659899662635-initial.ts3528
-rw-r--r--src/util/migrations/sqlite/1659921722863-premium_since_as_date.ts251
-rw-r--r--src/util/migrations/sqlite/1660130536131-updated-applications.ts828
-rw-r--r--src/util/migrations/sqlite/1660257576211-CodeCleanup1.ts325
-rw-r--r--src/util/migrations/sqlite/1660257795259-CodeCleanup2.ts571
-rw-r--r--src/util/migrations/sqlite/1660258351379-CodeCleanup3.ts230
-rw-r--r--src/util/migrations/sqlite/1660260672914-CodeCleanup4.ts458
-rw-r--r--src/util/migrations/sqlite/1660416010862-InvitersAreDeletable.ts245
-rw-r--r--src/util/migrations/sqlite/1660538628956-sync_migrations.ts171
-rw-r--r--src/util/migrations/sqlite/1660549233583-fix_nullables.ts239
-rw-r--r--src/util/schemas/ActivitySchema.ts (renamed from gateway/src/schema/Activity.ts)16
-rw-r--r--src/util/schemas/BanCreateSchema.ts4
-rw-r--r--src/util/schemas/BanModeratorSchema.ts7
-rw-r--r--src/util/schemas/BanRegistrySchema.ts8
-rw-r--r--src/util/schemas/BulkDeleteSchema.ts3
-rw-r--r--src/util/schemas/ChannelModifySchema.ts28
-rw-r--r--src/util/schemas/ChannelPermissionOverwriteSchema.ts5
-rw-r--r--src/util/schemas/ChannelReorderSchema.ts1
-rw-r--r--src/util/schemas/DmChannelCreateSchema.ts4
-rw-r--r--src/util/schemas/EmojiCreateSchema.ts6
-rw-r--r--src/util/schemas/EmojiModifySchema.ts4
-rw-r--r--src/util/schemas/GuildCreateSchema.ts14
-rw-r--r--src/util/schemas/GuildTemplateCreateSchema.ts4
-rw-r--r--src/util/schemas/GuildUpdateSchema.ts18
-rw-r--r--src/util/schemas/GuildUpdateWelcomeScreenSchema.ts10
-rw-r--r--src/util/schemas/IdentifySchema.ts (renamed from gateway/src/schema/Identify.ts)14
-rw-r--r--src/util/schemas/InviteCreateSchema.ts11
-rw-r--r--src/util/schemas/LazyRequestSchema.ts (renamed from gateway/src/schema/LazyRequest.ts)2
-rw-r--r--src/util/schemas/LoginSchema.ts8
-rw-r--r--src/util/schemas/MemberChangeSchema.ts3
-rw-r--r--src/util/schemas/MemberNickChangeSchema.ts3
-rw-r--r--src/util/schemas/MessageAcknowledgeSchema.ts8
-rw-r--r--src/util/schemas/MessageCreateSchema.ts33
-rw-r--r--src/util/schemas/MfaCodesSchema.ts4
-rw-r--r--src/util/schemas/ModifyGuildStickerSchema.ts15
-rw-r--r--src/util/schemas/PruneSchema.ts6
-rw-r--r--src/util/schemas/PurgeSchema.ts4
-rw-r--r--src/util/schemas/RegisterSchema.ts26
-rw-r--r--src/util/schemas/RelationshipPostSchema.ts4
-rw-r--r--src/util/schemas/RelationshipPutSchema.ts5
-rw-r--r--src/util/schemas/RoleModifySchema.ts10
-rw-r--r--src/util/schemas/RolePositionUpdateSchema.ts4
-rw-r--r--src/util/schemas/TemplateCreateSchema.ts4
-rw-r--r--src/util/schemas/TemplateModifySchema.ts4
-rw-r--r--src/util/schemas/TotpDisableSchema.ts3
-rw-r--r--src/util/schemas/TotpEnableSchema.ts5
-rw-r--r--src/util/schemas/TotpSchema.ts6
-rw-r--r--src/util/schemas/UserModifySchema.ts19
-rw-r--r--src/util/schemas/UserSettingsSchema.ts3
-rw-r--r--src/util/schemas/VanityUrlSchema.ts7
-rw-r--r--src/util/schemas/VoiceStateUpdateSchema.ts18
-rw-r--r--src/util/schemas/WebhookCreateSchema.ts8
-rw-r--r--src/util/schemas/WidgetModifySchema.ts4
-rw-r--r--src/util/schemas/index.ts43
-rw-r--r--src/util/util/ApiError.ts (renamed from util/src/util/ApiError.ts)3
-rw-r--r--src/util/util/Array.ts (renamed from util/src/util/Array.ts)0
-rw-r--r--src/util/util/AutoUpdate.ts (renamed from util/src/util/AutoUpdate.ts)13
-rw-r--r--src/util/util/BitField.ts (renamed from util/src/util/BitField.ts)3
-rw-r--r--src/util/util/Categories.ts (renamed from util/src/util/Categories.ts)2
-rw-r--r--src/util/util/Config.ts105
-rw-r--r--src/util/util/Constants.ts (renamed from util/src/util/Constants.ts)136
-rw-r--r--src/util/util/Database.ts107
-rw-r--r--src/util/util/Email.ts (renamed from util/src/util/Email.ts)2
-rw-r--r--src/util/util/Event.ts (renamed from util/src/util/Event.ts)17
-rw-r--r--src/util/util/FieldError.ts (renamed from util/src/util/FieldError.ts)8
-rw-r--r--src/util/util/Intents.ts (renamed from util/src/util/Intents.ts)5
-rw-r--r--src/util/util/InvisibleCharacters.ts57
-rw-r--r--src/util/util/MFA.ts18
-rw-r--r--src/util/util/MessageFlags.ts (renamed from util/src/util/MessageFlags.ts)2
-rw-r--r--src/util/util/Permissions.ts (renamed from util/src/util/Permissions.ts)48
-rw-r--r--src/util/util/RabbitMQ.ts (renamed from util/src/util/RabbitMQ.ts)4
-rw-r--r--src/util/util/Regex.ts (renamed from util/src/util/Regex.ts)0
-rw-r--r--src/util/util/Rights.ts (renamed from util/src/util/Rights.ts)24
-rw-r--r--src/util/util/Snowflake.ts (renamed from util/src/util/Snowflake.ts)17
-rw-r--r--src/util/util/String.ts (renamed from util/src/util/String.ts)0
-rw-r--r--src/util/util/Token.ts (renamed from util/src/util/Token.ts)17
-rw-r--r--src/util/util/TraverseDirectory.ts (renamed from util/src/util/TraverseDirectory.ts)9
-rw-r--r--src/util/util/cdn.ts (renamed from util/src/util/cdn.ts)13
-rw-r--r--src/util/util/imports/Checks.ts121
-rw-r--r--src/util/util/imports/HTTPError.ts5
-rw-r--r--src/util/util/imports/OrmUtils.ts96
-rw-r--r--src/util/util/imports/index.ts3
-rw-r--r--src/util/util/index.ts (renamed from util/src/util/index.ts)9
194 files changed, 12481 insertions, 1071 deletions
diff --git a/src/util/config/Config.ts b/src/util/config/Config.ts
new file mode 100644

index 00000000..36c4509d --- /dev/null +++ b/src/util/config/Config.ts
@@ -0,0 +1,46 @@ +import { + ApiConfiguration, + ClientConfiguration, + DefaultsConfiguration, + EndpointConfiguration, + GeneralConfiguration, + GifConfiguration, + GuildConfiguration, + KafkaConfiguration, + LimitsConfiguration, + LoginConfiguration, + MetricsConfiguration, + RabbitMQConfiguration, + RegionConfiguration, + RegisterConfiguration, + SecurityConfiguration, + SentryConfiguration, + TemplateConfiguration +} from "."; + +export class ConfigValue { + gateway: EndpointConfiguration = { + endpointPublic: '${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}', + endpointPrivate: `ws://localhost:3001` + }; + cdn: EndpointConfiguration = { + endpointPublic: "${location.host}", + endpointPrivate: `http://localhost:3001` + }; + api: ApiConfiguration = new ApiConfiguration(); + general: GeneralConfiguration = new GeneralConfiguration(); + limits: LimitsConfiguration = new LimitsConfiguration(); + security: SecurityConfiguration = new SecurityConfiguration(); + login: LoginConfiguration = new LoginConfiguration(); + register: RegisterConfiguration = new RegisterConfiguration(); + regions: RegionConfiguration = new RegionConfiguration(); + guild: GuildConfiguration = new GuildConfiguration(); + gif: GifConfiguration = new GifConfiguration(); + rabbitmq: RabbitMQConfiguration = new RabbitMQConfiguration(); + kafka: KafkaConfiguration = new KafkaConfiguration(); + templates: TemplateConfiguration = new TemplateConfiguration(); + client: ClientConfiguration = new ClientConfiguration(); + metrics: MetricsConfiguration = new MetricsConfiguration(); + sentry: SentryConfiguration = new SentryConfiguration(); + defaults: DefaultsConfiguration = new DefaultsConfiguration(); +} diff --git a/src/util/config/index.ts b/src/util/config/index.ts new file mode 100644
index 00000000..0a9b58ae --- /dev/null +++ b/src/util/config/index.ts
@@ -0,0 +1,2 @@ +export * from "./Config"; +export * from "./types/index"; diff --git a/src/util/config/types/ApiConfiguration.ts b/src/util/config/types/ApiConfiguration.ts new file mode 100644
index 00000000..442a5986 --- /dev/null +++ b/src/util/config/types/ApiConfiguration.ts
@@ -0,0 +1,5 @@ +export class ApiConfiguration { + defaultVersion: string = "9"; + activeVersions: string[] = ["6", "7", "8", "9"]; + useFosscordEnhancements: boolean = true; +} diff --git a/src/util/config/types/ClientConfiguration.ts b/src/util/config/types/ClientConfiguration.ts new file mode 100644
index 00000000..44704404 --- /dev/null +++ b/src/util/config/types/ClientConfiguration.ts
@@ -0,0 +1,8 @@ +import { ClientReleaseConfiguration } from "."; + +export class ClientConfiguration { + //classes + releases: ClientReleaseConfiguration = new ClientReleaseConfiguration(); + //base types + useTestClient: boolean = true; +} diff --git a/src/util/config/types/DefaultsConfiguration.ts b/src/util/config/types/DefaultsConfiguration.ts new file mode 100644
index 00000000..d5ee39e7 --- /dev/null +++ b/src/util/config/types/DefaultsConfiguration.ts
@@ -0,0 +1,6 @@ +import { GuildDefaults, UserDefaults } from "."; + +export class DefaultsConfiguration { + guild: GuildDefaults = new GuildDefaults(); + user: UserDefaults = new UserDefaults(); +} diff --git a/src/util/config/types/EndpointConfiguration.ts b/src/util/config/types/EndpointConfiguration.ts new file mode 100644
index 00000000..26f3106f --- /dev/null +++ b/src/util/config/types/EndpointConfiguration.ts
@@ -0,0 +1,4 @@ +export class EndpointConfiguration { + endpointPrivate: string | null = null; + endpointPublic: string | null = null; +} diff --git a/src/util/config/types/GeneralConfiguration.ts b/src/util/config/types/GeneralConfiguration.ts new file mode 100644
index 00000000..5cb8df89 --- /dev/null +++ b/src/util/config/types/GeneralConfiguration.ts
@@ -0,0 +1,12 @@ +import { Snowflake } from "../../util"; + +export class GeneralConfiguration { + instanceName: string = "Fosscord Instance"; + instanceDescription: string | null = "This is a Fosscord instance made in the pre-release days"; + frontPage: string | null = null; + tosPage: string | null = null; + correspondenceEmail: string | null = "noreply@localhost.local"; + correspondenceUserID: string | null = null; + image: string | null = null; + instanceId: string = Snowflake.generate(); +} diff --git a/src/util/config/types/GifConfiguration.ts b/src/util/config/types/GifConfiguration.ts new file mode 100644
index 00000000..565c2ac0 --- /dev/null +++ b/src/util/config/types/GifConfiguration.ts
@@ -0,0 +1,5 @@ +export class GifConfiguration { + enabled: boolean = true; + provider: "tenor" = "tenor"; // more coming soon + apiKey?: string = "LIVDSRZULELA"; +} diff --git a/src/util/config/types/GuildConfiguration.ts b/src/util/config/types/GuildConfiguration.ts new file mode 100644
index 00000000..ebc1b442 --- /dev/null +++ b/src/util/config/types/GuildConfiguration.ts
@@ -0,0 +1,6 @@ +import { AutoJoinConfiguration, DiscoveryConfiguration } from "."; + +export class GuildConfiguration { + discovery: DiscoveryConfiguration = new DiscoveryConfiguration(); + autoJoin: AutoJoinConfiguration = new AutoJoinConfiguration(); +} diff --git a/src/util/config/types/KafkaConfiguration.ts b/src/util/config/types/KafkaConfiguration.ts new file mode 100644
index 00000000..a3aa8058 --- /dev/null +++ b/src/util/config/types/KafkaConfiguration.ts
@@ -0,0 +1,5 @@ +import { KafkaBroker } from "."; + +export class KafkaConfiguration { + brokers: KafkaBroker[] | null = null; +} diff --git a/src/util/config/types/LimitConfigurations.ts b/src/util/config/types/LimitConfigurations.ts new file mode 100644
index 00000000..a3a52cf5 --- /dev/null +++ b/src/util/config/types/LimitConfigurations.ts
@@ -0,0 +1,9 @@ +import { ChannelLimits, GuildLimits, MessageLimits, RateLimits, UserLimits } from "."; + +export class LimitsConfiguration { + user: UserLimits = new UserLimits(); + guild: GuildLimits = new GuildLimits(); + message: MessageLimits = new MessageLimits(); + channel: ChannelLimits = new ChannelLimits(); + rate: RateLimits = new RateLimits(); +} diff --git a/src/util/config/types/LoginConfiguration.ts b/src/util/config/types/LoginConfiguration.ts new file mode 100644
index 00000000..d8b737b9 --- /dev/null +++ b/src/util/config/types/LoginConfiguration.ts
@@ -0,0 +1,3 @@ +export class LoginConfiguration { + requireCaptcha: boolean = false; +} diff --git a/src/util/config/types/MetricsConfiguration.ts b/src/util/config/types/MetricsConfiguration.ts new file mode 100644
index 00000000..f6b1d8e6 --- /dev/null +++ b/src/util/config/types/MetricsConfiguration.ts
@@ -0,0 +1,3 @@ +export class MetricsConfiguration { + timeout: number = 30000; +} diff --git a/src/util/config/types/RabbitMQConfiguration.ts b/src/util/config/types/RabbitMQConfiguration.ts new file mode 100644
index 00000000..bd4b6ca3 --- /dev/null +++ b/src/util/config/types/RabbitMQConfiguration.ts
@@ -0,0 +1,3 @@ +export class RabbitMQConfiguration { + host: string | null = null; +} diff --git a/src/util/config/types/RegionConfiguration.ts b/src/util/config/types/RegionConfiguration.ts new file mode 100644
index 00000000..b4b8c4a3 --- /dev/null +++ b/src/util/config/types/RegionConfiguration.ts
@@ -0,0 +1,16 @@ +import { Region } from "."; + +export class RegionConfiguration { + default: string = "fosscord"; + useDefaultAsOptimal: boolean = true; + available: Region[] = [ + { + id: "fosscord", + name: "Fosscord", + endpoint: "127.0.0.1:3004", + vip: false, + custom: false, + deprecated: false + } + ]; +} diff --git a/src/util/config/types/RegisterConfiguration.ts b/src/util/config/types/RegisterConfiguration.ts new file mode 100644
index 00000000..68946272 --- /dev/null +++ b/src/util/config/types/RegisterConfiguration.ts
@@ -0,0 +1,19 @@ +import { DateOfBirthConfiguration, EmailConfiguration, PasswordConfiguration } from "."; + +export class RegisterConfiguration { + //classes + email: EmailConfiguration = new EmailConfiguration(); + dateOfBirth: DateOfBirthConfiguration = new DateOfBirthConfiguration(); + password: PasswordConfiguration = new PasswordConfiguration(); + //base types + disabled: boolean = false; + requireCaptcha: boolean = true; + requireInvite: boolean = false; + allowGuests: boolean = true; + guestsRequireInvite: boolean = true; + allowNewRegistration: boolean = true; + allowMultipleAccounts: boolean = true; + blockProxies: boolean = true; + incrementingDiscriminators: boolean = false; // random otherwise + defaultRights: string = "0"; +} diff --git a/src/util/config/types/SecurityConfiguration.ts b/src/util/config/types/SecurityConfiguration.ts new file mode 100644
index 00000000..a2cebbd3 --- /dev/null +++ b/src/util/config/types/SecurityConfiguration.ts
@@ -0,0 +1,19 @@ +import crypto from "crypto"; +import { CaptchaConfiguration, TwoFactorConfiguration } from "."; + +export class SecurityConfiguration { + //classes + captcha: CaptchaConfiguration = new CaptchaConfiguration(); + twoFactor: TwoFactorConfiguration = new TwoFactorConfiguration(); + //base types + autoUpdate: boolean | number = true; + requestSignature: string = crypto.randomBytes(32).toString("base64"); + jwtSecret: string = crypto.randomBytes(256).toString("base64"); + // header to get the real user ip address + // X-Forwarded-For for nginx/reverse proxies + // CF-Connecting-IP for cloudflare + forwadedFor: string | null = null; + ipdataApiKey: string | null = "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9"; + mfaBackupCodeCount: number = 10; + mfaBackupCodeBytes: number = 4; +} diff --git a/src/util/config/types/SentryConfiguration.ts b/src/util/config/types/SentryConfiguration.ts new file mode 100644
index 00000000..d50f5f4c --- /dev/null +++ b/src/util/config/types/SentryConfiguration.ts
@@ -0,0 +1,8 @@ +import { hostname } from "os"; + +export class SentryConfiguration { + enabled: boolean = false; + endpoint: string = "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6"; + traceSampleRate: number = 1.0; + environment: string = hostname(); +} diff --git a/src/util/config/types/TemplateConfiguration.ts b/src/util/config/types/TemplateConfiguration.ts new file mode 100644
index 00000000..aade2934 --- /dev/null +++ b/src/util/config/types/TemplateConfiguration.ts
@@ -0,0 +1,6 @@ +export class TemplateConfiguration { + enabled: boolean = true; + allowTemplateCreation: boolean = true; + allowDiscordTemplates: boolean = true; + allowRaws: boolean = true; +} diff --git a/src/util/config/types/index.ts b/src/util/config/types/index.ts new file mode 100644
index 00000000..a8cdff4c --- /dev/null +++ b/src/util/config/types/index.ts
@@ -0,0 +1,18 @@ +export * from "./ApiConfiguration"; +export * from "./ClientConfiguration"; +export * from "./DefaultsConfiguration"; +export * from "./EndpointConfiguration"; +export * from "./GeneralConfiguration"; +export * from "./GifConfiguration"; +export * from "./GuildConfiguration"; +export * from "./KafkaConfiguration"; +export * from "./LimitConfigurations"; +export * from "./LoginConfiguration"; +export * from "./MetricsConfiguration"; +export * from "./RabbitMQConfiguration"; +export * from "./RegionConfiguration"; +export * from "./RegisterConfiguration"; +export * from "./SecurityConfiguration"; +export * from "./SentryConfiguration"; +export * from "./subconfigurations/index"; +export * from "./TemplateConfiguration"; diff --git a/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts new file mode 100644
index 00000000..b082b711 --- /dev/null +++ b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts
@@ -0,0 +1,4 @@ +export class ClientReleaseConfiguration { + useLocalRelease: boolean = true; //TODO + upstreamVersion: string = "0.0.264"; +} diff --git a/src/util/config/types/subconfigurations/client/index.ts b/src/util/config/types/subconfigurations/client/index.ts new file mode 100644
index 00000000..96bbb0ca --- /dev/null +++ b/src/util/config/types/subconfigurations/client/index.ts
@@ -0,0 +1 @@ +export * from "./ClientReleaseConfiguration"; diff --git a/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts b/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts new file mode 100644
index 00000000..435ae06c --- /dev/null +++ b/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts
@@ -0,0 +1,8 @@ +export class GuildDefaults { + maxPresences: number = 250000; + maxVideoChannelUsers: number = 200; + afkTimeout: number = 300; + defaultMessageNotifications: number = 1; + explicitContentFilter: number = 0; + test: number = 123; +} diff --git a/src/util/config/types/subconfigurations/defaults/UserDefaults.ts b/src/util/config/types/subconfigurations/defaults/UserDefaults.ts new file mode 100644
index 00000000..cc56be36 --- /dev/null +++ b/src/util/config/types/subconfigurations/defaults/UserDefaults.ts
@@ -0,0 +1,5 @@ +export class UserDefaults { + premium: boolean = false; + premium_type: number = 2; + verified: boolean = true; +} diff --git a/src/util/config/types/subconfigurations/defaults/index.ts b/src/util/config/types/subconfigurations/defaults/index.ts new file mode 100644
index 00000000..50258d1c --- /dev/null +++ b/src/util/config/types/subconfigurations/defaults/index.ts
@@ -0,0 +1,2 @@ +export * from "./GuildDefaults"; +export * from "./UserDefaults"; diff --git a/src/util/config/types/subconfigurations/guild/AutoJoin.ts b/src/util/config/types/subconfigurations/guild/AutoJoin.ts new file mode 100644
index 00000000..4d7af352 --- /dev/null +++ b/src/util/config/types/subconfigurations/guild/AutoJoin.ts
@@ -0,0 +1,5 @@ +export class AutoJoinConfiguration { + enabled: boolean = true; + guilds: string[] = []; + canLeave: boolean = true; +} diff --git a/src/util/config/types/subconfigurations/guild/Discovery.ts b/src/util/config/types/subconfigurations/guild/Discovery.ts new file mode 100644
index 00000000..a7cb81db --- /dev/null +++ b/src/util/config/types/subconfigurations/guild/Discovery.ts
@@ -0,0 +1,6 @@ +export class DiscoveryConfiguration { + showAllGuilds: boolean = false; + useRecommendation: boolean = false; // TODO: Recommendation, privacy concern? + offset: number = 0; + limit: number = 24; +} diff --git a/src/util/config/types/subconfigurations/guild/index.ts b/src/util/config/types/subconfigurations/guild/index.ts new file mode 100644
index 00000000..e9614856 --- /dev/null +++ b/src/util/config/types/subconfigurations/guild/index.ts
@@ -0,0 +1,2 @@ +export * from "./AutoJoin"; +export * from "./Discovery"; diff --git a/src/util/config/types/subconfigurations/index.ts b/src/util/config/types/subconfigurations/index.ts new file mode 100644
index 00000000..bfbadc92 --- /dev/null +++ b/src/util/config/types/subconfigurations/index.ts
@@ -0,0 +1,8 @@ +export * from "./client/index"; +export * from "./defaults/index"; +export * from "./guild/index"; +export * from "./kafka/index"; +export * from "./limits/index"; +export * from "./region/index"; +export * from "./register/index"; +export * from "./security/index"; diff --git a/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts b/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts new file mode 100644
index 00000000..f7dc1cf7 --- /dev/null +++ b/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts
@@ -0,0 +1,4 @@ +export interface KafkaBroker { + ip: string; + port: number; +} diff --git a/src/util/config/types/subconfigurations/kafka/index.ts b/src/util/config/types/subconfigurations/kafka/index.ts new file mode 100644
index 00000000..2c633950 --- /dev/null +++ b/src/util/config/types/subconfigurations/kafka/index.ts
@@ -0,0 +1 @@ +export * from "./KafkaBroker"; diff --git a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts new file mode 100644
index 00000000..76eeeb41 --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
@@ -0,0 +1,5 @@ +export class ChannelLimits { + maxPins: number = 500; + maxTopic: number = 1024; + maxWebhooks: number = 100; +} diff --git a/src/util/config/types/subconfigurations/limits/GuildLimits.ts b/src/util/config/types/subconfigurations/limits/GuildLimits.ts new file mode 100644
index 00000000..015654cb --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/GuildLimits.ts
@@ -0,0 +1,8 @@ +export class GuildLimits { + maxRoles: number = 1000; + maxEmojis: number = 2000; + maxMembers: number = 25000000; + maxChannels: number = 65535; + maxChannelsInCategory: number = 65535; + hideOfflineMember: number = 3; +} diff --git a/src/util/config/types/subconfigurations/limits/MessageLimits.ts b/src/util/config/types/subconfigurations/limits/MessageLimits.ts new file mode 100644
index 00000000..684a5057 --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/MessageLimits.ts
@@ -0,0 +1,8 @@ +export class MessageLimits { + maxCharacters: number = 1048576; + maxTTSCharacters: number = 160; + maxReactions: number = 2048; + maxAttachmentSize: number = 1024 * 1024 * 1024; + maxBulkDelete: number = 1000; + maxEmbedDownloadSize: number = 1024 * 1024 * 5; +} diff --git a/src/util/config/types/subconfigurations/limits/RateLimits.ts b/src/util/config/types/subconfigurations/limits/RateLimits.ts new file mode 100644
index 00000000..764acdd6 --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/RateLimits.ts
@@ -0,0 +1,18 @@ +import { RateLimitOptions, RouteRateLimit } from "."; + +export class RateLimits { + disabled: boolean = true; + ip: Omit<RateLimitOptions, "bot_count"> = { + count: 500, + window: 5 + }; + global: RateLimitOptions = { + count: 250, + window: 5 + }; + error: RateLimitOptions = { + count: 10, + window: 5 + }; + routes: RouteRateLimit = new RouteRateLimit(); +} diff --git a/src/util/config/types/subconfigurations/limits/UserLimits.ts b/src/util/config/types/subconfigurations/limits/UserLimits.ts new file mode 100644
index 00000000..b8bdcb2d --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/UserLimits.ts
@@ -0,0 +1,5 @@ +export class UserLimits { + maxGuilds: number = 1048576; + maxUsername: number = 127; + maxFriends: number = 5000; +} diff --git a/src/util/config/types/subconfigurations/limits/index.ts b/src/util/config/types/subconfigurations/limits/index.ts new file mode 100644
index 00000000..a4911542 --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/index.ts
@@ -0,0 +1,6 @@ +export * from "./ChannelLimits"; +export * from "./GuildLimits"; +export * from "./MessageLimits"; +export * from "./RateLimits"; +export * from "./ratelimits/index"; +export * from "./UserLimits"; diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts b/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts new file mode 100644
index 00000000..0f363e7f --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts
@@ -0,0 +1,12 @@ +import { RateLimitOptions } from "./RateLimitOptions"; + +export class AuthRateLimit { + login: RateLimitOptions = { + count: 5, + window: 60 + }; + register: RateLimitOptions = { + count: 2, + window: 60 * 60 * 12 + }; +} diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts b/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts new file mode 100644
index 00000000..829813fb --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts
@@ -0,0 +1,6 @@ +export interface RateLimitOptions { + bot?: number; + count: number; + window: number; + onyIp?: boolean; +} diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts b/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts new file mode 100644
index 00000000..6890699e --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts
@@ -0,0 +1,19 @@ +import { AuthRateLimit } from "./Auth"; +import { RateLimitOptions } from "./RateLimitOptions"; + +export class RouteRateLimit { + guild: RateLimitOptions = { + count: 5, + window: 5 + }; + webhook: RateLimitOptions = { + count: 10, + window: 5 + }; + channel: RateLimitOptions = { + count: 10, + window: 5 + }; + auth: AuthRateLimit = new AuthRateLimit(); + // TODO: rate limit configuration for all routes +} diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/index.ts b/src/util/config/types/subconfigurations/limits/ratelimits/index.ts new file mode 100644
index 00000000..432eb601 --- /dev/null +++ b/src/util/config/types/subconfigurations/limits/ratelimits/index.ts
@@ -0,0 +1,3 @@ +export * from "./Auth"; +export * from "./RateLimitOptions"; +export * from "./Route"; diff --git a/src/util/config/types/subconfigurations/region/Region.ts b/src/util/config/types/subconfigurations/region/Region.ts new file mode 100644
index 00000000..c1bcfd01 --- /dev/null +++ b/src/util/config/types/subconfigurations/region/Region.ts
@@ -0,0 +1,12 @@ +export interface Region { + id: string; + name: string; + endpoint: string; + location?: { + latitude: number; + longitude: number; + }; + vip: boolean; + custom: boolean; + deprecated: boolean; +} diff --git a/src/util/config/types/subconfigurations/region/index.ts b/src/util/config/types/subconfigurations/region/index.ts new file mode 100644
index 00000000..2beb8de7 --- /dev/null +++ b/src/util/config/types/subconfigurations/region/index.ts
@@ -0,0 +1 @@ +export * from "./Region"; diff --git a/src/util/config/types/subconfigurations/register/DateOfBirth.ts b/src/util/config/types/subconfigurations/register/DateOfBirth.ts new file mode 100644
index 00000000..4831a4b7 --- /dev/null +++ b/src/util/config/types/subconfigurations/register/DateOfBirth.ts
@@ -0,0 +1,4 @@ +export class DateOfBirthConfiguration { + required: boolean = true; + minimum: number = 13; // in years +} diff --git a/src/util/config/types/subconfigurations/register/Email.ts b/src/util/config/types/subconfigurations/register/Email.ts new file mode 100644
index 00000000..7f54faa7 --- /dev/null +++ b/src/util/config/types/subconfigurations/register/Email.ts
@@ -0,0 +1,7 @@ +export class EmailConfiguration { + required: boolean = false; + allowlist: boolean = false; + blocklist: boolean = true; + domains: string[] = []; // TODO: efficiently save domain blocklist in database + // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), +} diff --git a/src/util/config/types/subconfigurations/register/Password.ts b/src/util/config/types/subconfigurations/register/Password.ts new file mode 100644
index 00000000..383bdcfa --- /dev/null +++ b/src/util/config/types/subconfigurations/register/Password.ts
@@ -0,0 +1,7 @@ +export class PasswordConfiguration { + required: boolean = false; + minLength: number = 8; + minNumbers: number = 2; + minUpperCase: number = 2; + minSymbols: number = 0; +} diff --git a/src/util/config/types/subconfigurations/register/index.ts b/src/util/config/types/subconfigurations/register/index.ts new file mode 100644
index 00000000..d9738120 --- /dev/null +++ b/src/util/config/types/subconfigurations/register/index.ts
@@ -0,0 +1,3 @@ +export * from "./DateOfBirth"; +export * from "./Email"; +export * from "./Password"; diff --git a/src/util/config/types/subconfigurations/security/Captcha.ts b/src/util/config/types/subconfigurations/security/Captcha.ts new file mode 100644
index 00000000..21c4ef44 --- /dev/null +++ b/src/util/config/types/subconfigurations/security/Captcha.ts
@@ -0,0 +1,6 @@ +export class CaptchaConfiguration { + enabled: boolean = false; + service: "recaptcha" | "hcaptcha" | null = null; // TODO: hcaptcha, custom + sitekey: string | null = null; + secret: string | null = null; +} diff --git a/src/util/config/types/subconfigurations/security/TwoFactor.ts b/src/util/config/types/subconfigurations/security/TwoFactor.ts new file mode 100644
index 00000000..20d2f9ab --- /dev/null +++ b/src/util/config/types/subconfigurations/security/TwoFactor.ts
@@ -0,0 +1,3 @@ +export class TwoFactorConfiguration { + generateBackupCodes: boolean = true; +} diff --git a/src/util/config/types/subconfigurations/security/index.ts b/src/util/config/types/subconfigurations/security/index.ts new file mode 100644
index 00000000..17619589 --- /dev/null +++ b/src/util/config/types/subconfigurations/security/index.ts
@@ -0,0 +1,2 @@ +export * from "./Captcha"; +export * from "./TwoFactor"; diff --git a/util/src/dtos/DmChannelDTO.ts b/src/util/dtos/DmChannelDTO.ts
index 226b2f9d..93b1adfa 100644 --- a/util/src/dtos/DmChannelDTO.ts +++ b/src/util/dtos/DmChannelDTO.ts
@@ -1,5 +1,5 @@ -import { MinimalPublicUserDTO } from "./UserDTO"; import { Channel, PublicUserProjection, User } from "../entities"; +import { MinimalPublicUserDTO } from "./UserDTO"; export class DmChannelDTO { icon: string | null; @@ -35,7 +35,7 @@ export class DmChannelDTO { excludedRecipients(excluded_recipients: string[]): DmChannelDTO { return { ...this, - recipients: this.recipients.filter((r) => !excluded_recipients.includes(r.id)), + recipients: this.recipients.filter((r) => !excluded_recipients.includes(r.id)) }; } } diff --git a/util/src/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts
index ee2752a4..ee2752a4 100644 --- a/util/src/dtos/UserDTO.ts +++ b/src/util/dtos/UserDTO.ts
diff --git a/util/src/dtos/index.ts b/src/util/dtos/index.ts
index 0e8f8459..0e8f8459 100644 --- a/util/src/dtos/index.ts +++ b/src/util/dtos/index.ts
diff --git a/util/src/entities/Application.ts b/src/util/entities/Application.ts
index fab3d93f..35fc496d 100644 --- a/util/src/entities/Application.ts +++ b/src/util/entities/Application.ts
@@ -1,6 +1,5 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from "typeorm"; import { BaseClass } from "./BaseClass"; -import { Guild } from "./Guild"; import { Team } from "./Team"; import { User } from "./User"; @@ -12,55 +11,101 @@ export class Application extends BaseClass { @Column({ nullable: true }) icon?: string; - @Column() + @Column({ nullable: true }) description: string; - @Column({ type: "simple-array", nullable: true }) - rpc_origins?: string[]; + @Column({ nullable: true }) + summary: string = ""; + + @Column({ type: "simple-json", nullable: true }) + type?: any; @Column() - bot_public: boolean; + hook: boolean = true; @Column() - bot_require_code_grant: boolean; + bot_public?: boolean = true; - @Column({ nullable: true }) - terms_of_service_url?: string; + @Column() + bot_require_code_grant?: boolean = false; - @Column({ nullable: true }) - privacy_policy_url?: string; + @Column() + verify_key: string; @JoinColumn({ name: "owner_id" }) @ManyToOne(() => User) - owner?: User; + owner: User; + + @Column() + flags: number = 0; + + @Column({ type: "simple-array", nullable: true }) + redirect_uris: string[] = []; @Column({ nullable: true }) - summary?: string; + rpc_application_state: number = 0; - @Column() - verify_key: string; + @Column({ nullable: true }) + store_application_state: number = 1; - @JoinColumn({ name: "team_id" }) - @ManyToOne(() => Team, { - onDelete: "CASCADE", - }) - team?: Team; + @Column({ nullable: true }) + verification_state: number = 1; - @JoinColumn({ name: "guild_id" }) - @ManyToOne(() => Guild) - guild: Guild; // if this application is a game sold, this field will be the guild to which it has been linked + @Column({ nullable: true }) + interactions_endpoint_url?: string; @Column({ nullable: true }) - primary_sku_id?: string; // if this application is a game sold, this field will be the id of the "Game SKU" that is created, + integration_public: boolean = true; @Column({ nullable: true }) - slug?: string; // if this application is a game sold, this field will be the URL slug that links to the store page + integration_require_code_grant: boolean = false; + + @Column({ nullable: true }) + discoverability_state: number = 1; + + @Column({ nullable: true }) + discovery_eligibility_flags: number = 2240; + + @JoinColumn({ name: "bot_user_id" }) + @OneToOne(() => User) + bot?: User; + + @Column({ type: "simple-array", nullable: true }) + tags?: string[]; @Column({ nullable: true }) cover_image?: string; // the application's default rich presence invite cover image hash - @Column() - flags: string; // the application's public flags + @Column({ type: "simple-json", nullable: true }) + install_params?: { scopes: string[]; permissions: string }; + + @Column({ nullable: true }) + terms_of_service_url?: string; + + @Column({ nullable: true }) + privacy_policy_url?: string; + + //just for us + + //@Column({ type: "simple-array", nullable: true }) + //rpc_origins?: string[]; + + //@JoinColumn({ name: "guild_id" }) + //@ManyToOne(() => Guild) + //guild?: Guild; // if this application is a game sold, this field will be the guild to which it has been linked + + //@Column({ nullable: true }) + //primary_sku_id?: string; // if this application is a game sold, this field will be the id of the "Game SKU" that is created, + + //@Column({ nullable: true }) + //slug?: string; // if this application is a game sold, this field will be the URL slug that links to the store page + + @JoinColumn({ name: "team_id" }) + @ManyToOne(() => Team, { + onDelete: "CASCADE", + nullable: true + }) + team?: Team; } export interface ApplicationCommand { @@ -93,7 +138,7 @@ export enum ApplicationCommandOptionType { BOOLEAN = 5, USER = 6, CHANNEL = 7, - ROLE = 8, + ROLE = 8 } export interface ApplicationCommandInteractionData { diff --git a/util/src/entities/Attachment.ts b/src/util/entities/Attachment.ts
index 7b4b17eb..8392f415 100644 --- a/util/src/entities/Attachment.ts +++ b/src/util/entities/Attachment.ts
@@ -32,7 +32,7 @@ export class Attachment extends BaseClass { @JoinColumn({ name: "message_id" }) @ManyToOne(() => require("./Message").Message, (message: import("./Message").Message) => message.attachments, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) message: import("./Message").Message; diff --git a/util/src/entities/AuditLog.ts b/src/util/entities/AuditLog.ts
index b003e7ba..6f394f42 100644 --- a/util/src/entities/AuditLog.ts +++ b/src/util/entities/AuditLog.ts
@@ -5,24 +5,24 @@ import { User } from "./User"; export enum AuditLogEvents { // guild level - GUILD_UPDATE = 1, + GUILD_UPDATE = 1, GUILD_IMPORT = 2, GUILD_EXPORTED = 3, GUILD_ARCHIVE = 4, GUILD_UNARCHIVE = 5, // join-leave - USER_JOIN = 6, + USER_JOIN = 6, USER_LEAVE = 7, // channels - CHANNEL_CREATE = 10, + CHANNEL_CREATE = 10, CHANNEL_UPDATE = 11, CHANNEL_DELETE = 12, // permission overrides - CHANNEL_OVERWRITE_CREATE = 13, + CHANNEL_OVERWRITE_CREATE = 13, CHANNEL_OVERWRITE_UPDATE = 14, CHANNEL_OVERWRITE_DELETE = 15, // kick and ban - MEMBER_KICK = 20, + MEMBER_KICK = 20, MEMBER_PRUNE = 21, MEMBER_BAN_ADD = 22, MEMBER_BAN_REMOVE = 23, @@ -79,18 +79,18 @@ export enum AuditLogEvents { // application commands APPLICATION_COMMAND_PERMISSION_UPDATE = 121, // automod - POLICY_CREATE = 140, + POLICY_CREATE = 140, POLICY_UPDATE = 141, POLICY_DELETE = 142, - MESSAGE_BLOCKED_BY_POLICIES = 143, // in fosscord, blocked messages are stealth-dropped + MESSAGE_BLOCKED_BY_POLICIES = 143, // in fosscord, blocked messages are stealth-dropped // instance policies affecting the guild GUILD_AFFECTED_BY_POLICIES = 216, // message moves IN_GUILD_MESSAGE_MOVE = 223, CROSS_GUILD_MESSAGE_MOVE = 224, // message routing - ROUTE_CREATE = 225, - ROUTE_UPDATE = 226, + ROUTE_CREATE = 225, + ROUTE_UPDATE = 226 } @Entity("audit_logs") diff --git a/src/util/entities/BackupCodes.ts b/src/util/entities/BackupCodes.ts new file mode 100644
index 00000000..503b1dbd --- /dev/null +++ b/src/util/entities/BackupCodes.ts
@@ -0,0 +1,19 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; + +@Entity("backup_codes") +export class BackupCode extends BaseClass { + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, { onDelete: "CASCADE" }) + user: User; + + @Column() + code: string; + + @Column() + consumed: boolean; + + @Column() + expired: boolean; +} diff --git a/util/src/entities/Ban.ts b/src/util/entities/Ban.ts
index 9504bd8e..27c75278 100644 --- a/util/src/entities/Ban.ts +++ b/src/util/entities/Ban.ts
@@ -11,7 +11,7 @@ export class Ban extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; @@ -21,7 +21,7 @@ export class Ban extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts new file mode 100644
index 00000000..aecc2465 --- /dev/null +++ b/src/util/entities/BaseClass.ts
@@ -0,0 +1,26 @@ +import "reflect-metadata"; +import { BaseEntity, ObjectIdColumn, PrimaryColumn, SaveOptions } from "typeorm"; +import { Snowflake } from "../util/Snowflake"; + +export class BaseClassWithoutId extends BaseEntity { + constructor() { + super(); + } +} + +export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn; + +export class BaseClass extends BaseClassWithoutId { + @PrimaryIdColumn() + id: string; + + constructor() { + super(); + if (!this.id) this.id = Snowflake.generate(); + } + + save(options?: SaveOptions | undefined): Promise<this> { + if (!this.id) this.id = Snowflake.generate(); + return super.save(options); + } +} diff --git a/util/src/entities/Categories.ts b/src/util/entities/Categories.ts
index 81fbc303..08a79112 100644 --- a/util/src/entities/Categories.ts +++ b/src/util/entities/Categories.ts
@@ -1,4 +1,4 @@ -import { PrimaryColumn, Column, Entity} from "typeorm"; +import { Column, Entity, PrimaryColumn } from "typeorm"; import { BaseClassWithoutId } from "./BaseClass"; // TODO: categories: @@ -16,18 +16,18 @@ import { BaseClassWithoutId } from "./BaseClass"; // Also populate discord default categories @Entity("categories") -export class Categories extends BaseClassWithoutId { // Not using snowflake - - @PrimaryColumn() - id: number; +export class Categories extends BaseClassWithoutId { + // Not using snowflake - @Column({ nullable: true }) - name: string; + @PrimaryColumn() + id: number; - @Column({ type: "simple-json" }) - localizations: string; + @Column({ nullable: true }) + name: string; - @Column({ nullable: true }) - is_primary: boolean; + @Column({ type: "simple-json" }) + localizations: string; -} \ No newline at end of file + @Column({ nullable: true }) + is_primary: boolean; +} diff --git a/util/src/entities/Channel.ts b/src/util/entities/Channel.ts
index 69c08be7..b17fdba0 100644 --- a/util/src/entities/Channel.ts +++ b/src/util/entities/Channel.ts
@@ -1,380 +1,389 @@ -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; -import { BaseClass } from "./BaseClass"; -import { Guild } from "./Guild"; -import { PublicUserProjection, User } from "./User"; -import { HTTPError } from "lambert-server"; -import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util"; -import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces"; -import { Recipient } from "./Recipient"; -import { Message } from "./Message"; -import { ReadState } from "./ReadState"; -import { Invite } from "./Invite"; -import { VoiceState } from "./VoiceState"; -import { Webhook } from "./Webhook"; -import { DmChannelDTO } from "../dtos"; - -export enum ChannelType { - GUILD_TEXT = 0, // a text channel within a guild - DM = 1, // a direct message between users - GUILD_VOICE = 2, // a voice channel within a guild - GROUP_DM = 3, // a direct message between multiple users - GUILD_CATEGORY = 4, // an organizational category that contains zero or more channels - GUILD_NEWS = 5, // a channel that users can follow and crosspost into a guild or route - GUILD_STORE = 6, // a channel in which game developers can sell their things - ENCRYPTED = 7, // end-to-end encrypted channel - ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel - TRANSACTIONAL = 9, // event chain style transactional channel - GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel - GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel - GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission - GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience - DIRECTORY = 14, // guild directory listing channel - GUILD_FORUM = 15, // forum composed of IM threads - TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12 - KANBAN = 34, // confluence like kanban board - VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage) - CUSTOM_START = 64, // start custom channel types from here - UNHANDLED = 255 // unhandled unowned pass-through channel type -} - -@Entity("channels") -export class Channel extends BaseClass { - @Column() - created_at: Date; - - @Column({ nullable: true }) - name?: string; - - @Column({ type: "text", nullable: true }) - icon?: string | null; - - @Column({ type: "int" }) - type: ChannelType; - - @OneToMany(() => Recipient, (recipient: Recipient) => recipient.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - recipients?: Recipient[]; - - @Column({ nullable: true }) - last_message_id: string; - - @Column({ nullable: true }) - @RelationId((channel: Channel) => channel.guild) - guild_id?: string; - - @JoinColumn({ name: "guild_id" }) - @ManyToOne(() => Guild, { - onDelete: "CASCADE", - }) - guild: Guild; - - @Column({ nullable: true }) - @RelationId((channel: Channel) => channel.parent) - parent_id: string; - - @JoinColumn({ name: "parent_id" }) - @ManyToOne(() => Channel) - parent?: Channel; - - // for group DMs and owned custom channel types - @Column({ nullable: true }) - @RelationId((channel: Channel) => channel.owner) - owner_id: string; - - @JoinColumn({ name: "owner_id" }) - @ManyToOne(() => User) - owner: User; - - @Column({ nullable: true }) - last_pin_timestamp?: number; - - @Column({ nullable: true }) - default_auto_archive_duration?: number; - - @Column({ nullable: true }) - position?: number; - - @Column({ type: "simple-json", nullable: true }) - permission_overwrites?: ChannelPermissionOverwrite[]; - - @Column({ nullable: true }) - video_quality_mode?: number; - - @Column({ nullable: true }) - bitrate?: number; - - @Column({ nullable: true }) - user_limit?: number; - - @Column({ nullable: true }) - nsfw?: boolean; - - @Column({ nullable: true }) - rate_limit_per_user?: number; - - @Column({ nullable: true }) - topic?: string; - - @OneToMany(() => Invite, (invite: Invite) => invite.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - invites?: Invite[]; - - @Column({ nullable: true }) - retention_policy_id?: string; - - @OneToMany(() => Message, (message: Message) => message.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - messages?: Message[]; - - @OneToMany(() => VoiceState, (voice_state: VoiceState) => voice_state.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - voice_states?: VoiceState[]; - - @OneToMany(() => ReadState, (read_state: ReadState) => read_state.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - read_states?: ReadState[]; - - @OneToMany(() => Webhook, (webhook: Webhook) => webhook.channel, { - cascade: true, - orphanedRowAction: "delete", - }) - webhooks?: Webhook[]; - - // TODO: DM channel - static async createChannel( - channel: Partial<Channel>, - user_id: string = "0", - opts?: { - keepId?: boolean; - skipExistsCheck?: boolean; - skipPermissionCheck?: boolean; - skipEventEmit?: boolean; - skipNameChecks?: boolean; - } - ) { - if (!opts?.skipPermissionCheck) { - // Always check if user has permission first - const permissions = await getPermission(user_id, channel.guild_id); - permissions.hasThrow("MANAGE_CHANNELS"); - } - - if (!opts?.skipNameChecks) { - const guild = await Guild.findOneOrFail({ id: channel.guild_id }); - if (!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") && channel.name) { - for (var character of InvisibleCharacters) - if (channel.name.includes(character)) - throw new HTTPError("Channel name cannot include invalid characters", 403); - - if (channel.name.match(/\-\-+/g)) - throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403) - - if (channel.name.charAt(0) === "-" || - channel.name.charAt(channel.name.length - 1) === "-") - throw new HTTPError("Channel name cannot start/end with dash.", 403) - } - - if (!guild.features.includes("ALLOW_UNNAMED_CHANNELS")) { - if (!channel.name) - throw new HTTPError("Channel name cannot be empty.", 403); - } - } - - switch (channel.type) { - case ChannelType.GUILD_TEXT: - case ChannelType.GUILD_NEWS: - case ChannelType.GUILD_VOICE: - if (channel.parent_id && !opts?.skipExistsCheck) { - const exists = await Channel.findOneOrFail({ id: channel.parent_id }); - if (!exists) throw new HTTPError("Parent id channel doesn't exist", 400); - if (exists.guild_id !== channel.guild_id) - throw new HTTPError("The category channel needs to be in the guild"); - } - break; - case ChannelType.GUILD_CATEGORY: - case ChannelType.UNHANDLED: - break; - case ChannelType.DM: - case ChannelType.GROUP_DM: - throw new HTTPError("You can't create a dm channel in a guild"); - case ChannelType.GUILD_STORE: - default: - throw new HTTPError("Not yet supported"); - } - - if (!channel.permission_overwrites) channel.permission_overwrites = []; - // TODO: eagerly auto generate position of all guild channels - - channel = { - ...channel, - ...(!opts?.keepId && { id: Snowflake.generate() }), - created_at: new Date(), - position: (channel.type === ChannelType.UNHANDLED ? 0 : channel.position) || 0, - }; - - await Promise.all([ - new Channel(channel).save(), - !opts?.skipEventEmit - ? emitEvent({ - event: "CHANNEL_CREATE", - data: channel, - guild_id: channel.guild_id, - } as ChannelCreateEvent) - : Promise.resolve(), - ]); - - return channel; - } - - static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) { - recipients = recipients.unique().filter((x) => x !== creator_user_id); - const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) }); - - // TODO: check config for max number of recipients - /** if you want to disallow note to self channels, uncomment the conditional below - if (otherRecipientsUsers.length !== recipients.length) { - throw new HTTPError("Recipient/s not found"); - } - **/ - - const type = recipients.length > 1 ? ChannelType.DM : ChannelType.GROUP_DM; - - let channel = null; - - const channelRecipients = [...recipients, creator_user_id]; - - const userRecipients = await Recipient.find({ - where: { user_id: creator_user_id }, - relations: ["channel", "channel.recipients"], - }); - - for (let ur of userRecipients) { - let re = ur.channel.recipients!.map((r) => r.user_id); - if (re.length === channelRecipients.length) { - if (containsAll(re, channelRecipients)) { - if (channel == null) { - channel = ur.channel; - await ur.assign({ closed: false }).save(); - } - } - } - } - - if (channel == null) { - name = trimSpecial(name); - - channel = await new Channel({ - name, - type, - owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server - created_at: new Date(), - last_message_id: null, - recipients: channelRecipients.map( - (x) => - new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) }) - ), - }).save(); - } - - const channel_dto = await DmChannelDTO.from(channel); - - if (type === ChannelType.GROUP_DM) { - for (let recipient of channel.recipients!) { - await emitEvent({ - event: "CHANNEL_CREATE", - data: channel_dto.excludedRecipients([recipient.user_id]), - user_id: recipient.user_id, - }); - } - } else { - await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id }); - } - - if (recipients.length === 1) return channel_dto; - else return channel_dto.excludedRecipients([creator_user_id]); - } - - static async removeRecipientFromChannel(channel: Channel, user_id: string) { - await Recipient.delete({ channel_id: channel.id, user_id: user_id }); - channel.recipients = channel.recipients?.filter((r) => r.user_id !== user_id); - - if (channel.recipients?.length === 0) { - await Channel.deleteChannel(channel); - await emitEvent({ - event: "CHANNEL_DELETE", - data: await DmChannelDTO.from(channel, [user_id]), - user_id: user_id, - }); - return; - } - - await emitEvent({ - event: "CHANNEL_DELETE", - data: await DmChannelDTO.from(channel, [user_id]), - user_id: user_id, - }); - - //If the owner leave the server user is the new owner - if (channel.owner_id === user_id) { - channel.owner_id = "1"; // The channel is now owned by the server user - await emitEvent({ - event: "CHANNEL_UPDATE", - data: await DmChannelDTO.from(channel, [user_id]), - channel_id: channel.id, - }); - } - - await channel.save(); - - await emitEvent({ - event: "CHANNEL_RECIPIENT_REMOVE", - data: { - channel_id: channel.id, - user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection }), - }, - channel_id: channel.id, - } as ChannelRecipientRemoveEvent); - } - - static async deleteChannel(channel: Channel) { - await Message.delete({ channel_id: channel.id }); //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util - //TODO before deleting the channel we should check and delete other relations - await Channel.delete({ id: channel.id }); - } - - isDm() { - return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM; - } - - // Does the channel support sending messages ( eg categories do not ) - isWritable() { - const disallowedChannelTypes = [ - ChannelType.GUILD_CATEGORY, - ChannelType.GUILD_STAGE_VOICE, - ChannelType.VOICELESS_WHITEBOARD, - ]; - return disallowedChannelTypes.indexOf(this.type) == -1; - } -} - -export interface ChannelPermissionOverwrite { - allow: string; - deny: string; - id: string; - type: ChannelPermissionOverwriteType; -} - -export enum ChannelPermissionOverwriteType { - role = 0, - member = 1, - group = 2, -} +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; +import { DmChannelDTO } from "../dtos"; +import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces"; +import { containsAll, emitEvent, getPermission, InvisibleCharacters, Snowflake, trimSpecial } from "../util"; +import { HTTPError } from "../util/imports/HTTPError"; +import { OrmUtils } from "../util/imports/OrmUtils"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Invite } from "./Invite"; +import { Message } from "./Message"; +import { ReadState } from "./ReadState"; +import { Recipient } from "./Recipient"; +import { PublicUserProjection, User } from "./User"; +import { VoiceState } from "./VoiceState"; +import { Webhook } from "./Webhook"; + +export enum ChannelType { + GUILD_TEXT = 0, // a text channel within a guild + DM = 1, // a direct message between users + GUILD_VOICE = 2, // a voice channel within a guild + GROUP_DM = 3, // a direct message between multiple users + GUILD_CATEGORY = 4, // an organizational category that contains zero or more channels + GUILD_NEWS = 5, // a channel that users can follow and crosspost into a guild or route + GUILD_STORE = 6, // a channel in which game developers can sell their things + ENCRYPTED = 7, // end-to-end encrypted channel + ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel + TRANSACTIONAL = 9, // event chain style transactional channel + GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel + GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel + GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission + GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience + DIRECTORY = 14, // guild directory listing channel + GUILD_FORUM = 15, // forum composed of IM threads + TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12 + KANBAN = 34, // confluence like kanban board + VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage) + CUSTOM_START = 64, // start custom channel types from here + UNHANDLED = 255 // unhandled unowned pass-through channel type +} + +@Entity("channels") +export class Channel extends BaseClass { + @Column() + created_at: Date; + + @Column({ nullable: true }) + name?: string; + + @Column({ type: "text", nullable: true }) + icon?: string | null; + + @Column({ type: "int" }) + type: ChannelType; + + @OneToMany(() => Recipient, (recipient: Recipient) => recipient.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + recipients?: Recipient[]; + + @Column({ nullable: true }) + last_message_id: string; + + @Column({ nullable: true }) + @RelationId((channel: Channel) => channel.guild) + guild_id?: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, { + onDelete: "CASCADE" + }) + guild: Guild; + + @Column({ nullable: true }) + @RelationId((channel: Channel) => channel.parent) + parent_id: string; + + @JoinColumn({ name: "parent_id" }) + @ManyToOne(() => Channel) + parent?: Channel; + + // for group DMs and owned custom channel types + @Column({ nullable: true }) + @RelationId((channel: Channel) => channel.owner) + owner_id: string; + + @JoinColumn({ name: "owner_id" }) + @ManyToOne(() => User) + owner: User; + + @Column({ nullable: true }) + last_pin_timestamp?: number; + + @Column({ nullable: true }) + default_auto_archive_duration?: number; + + @Column({ nullable: true }) + position?: number; + + @Column({ type: "simple-json", nullable: true }) + permission_overwrites?: ChannelPermissionOverwrite[]; + + @Column({ nullable: true }) + video_quality_mode?: number; + + @Column({ nullable: true }) + bitrate?: number; + + @Column({ nullable: true }) + user_limit?: number; + + @Column({ nullable: true }) + nsfw?: boolean; + + @Column({ nullable: true }) + rate_limit_per_user?: number; + + @Column({ nullable: true }) + topic?: string; + + @OneToMany(() => Invite, (invite: Invite) => invite.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + invites?: Invite[]; + + @Column({ nullable: true }) + retention_policy_id?: string; + + @OneToMany(() => Message, (message: Message) => message.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + messages?: Message[]; + + @OneToMany(() => VoiceState, (voice_state: VoiceState) => voice_state.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + voice_states?: VoiceState[]; + + @OneToMany(() => ReadState, (read_state: ReadState) => read_state.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + read_states?: ReadState[]; + + @OneToMany(() => Webhook, (webhook: Webhook) => webhook.channel, { + cascade: true, + orphanedRowAction: "delete" + }) + webhooks?: Webhook[]; + + @Column({ nullable: true }) + flags?: number = 0; + + @Column({ nullable: true }) + default_thread_rate_limit_per_user?: number = 0; + + // TODO: DM channel + static async createChannel( + channel: Partial<Channel>, + user_id: string = "0", + opts?: { + keepId?: boolean; + skipExistsCheck?: boolean; + skipPermissionCheck?: boolean; + skipEventEmit?: boolean; + skipNameChecks?: boolean; + } + ) { + if (!opts?.skipPermissionCheck) { + // Always check if user has permission first + const permissions = await getPermission(user_id, channel.guild_id); + permissions.hasThrow("MANAGE_CHANNELS"); + } + + if (!opts?.skipNameChecks) { + const guild = await Guild.findOneOrFail({ where: { id: channel.guild_id } }); + if (!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") && channel.name) { + for (let character of InvisibleCharacters) + if (channel.name.includes(character)) throw new HTTPError("Channel name cannot include invalid characters", 403); + + // Categories and voice skip these checks on discord.com + const skipChecksTypes = [ChannelType.GUILD_CATEGORY, ChannelType.GUILD_VOICE]; + if ((channel.type && !skipChecksTypes.includes(channel.type)) || guild.features.includes("IRC_LIKE_CHANNEL_NAMES")) { + if (channel.name.includes(" ")) throw new HTTPError("Channel name cannot include invalid characters", 403); + + if (channel.name.match(/\-\-+/g)) throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403); + + if (channel.name.charAt(0) === "-" || channel.name.charAt(channel.name.length - 1) === "-") + throw new HTTPError("Channel name cannot start/end with dash.", 403); + } else channel.name = channel.name.trim(); //category names are trimmed client side on discord.com + } + + if (!guild.features.includes("ALLOW_UNNAMED_CHANNELS")) { + if (!channel.name) throw new HTTPError("Channel name cannot be empty.", 403); + } + } + + switch (channel.type) { + case ChannelType.GUILD_TEXT: + case ChannelType.GUILD_NEWS: + case ChannelType.GUILD_VOICE: + if (channel.parent_id && !opts?.skipExistsCheck) { + const exists = await Channel.findOneOrFail({ where: { id: channel.parent_id } }); + if (!exists) throw new HTTPError("Parent id channel doesn't exist", 400); + if (exists.guild_id !== channel.guild_id) throw new HTTPError("The category channel needs to be in the guild"); + } + break; + case ChannelType.GUILD_CATEGORY: + case ChannelType.UNHANDLED: + break; + case ChannelType.DM: + case ChannelType.GROUP_DM: + throw new HTTPError("You can't create a dm channel in a guild"); + case ChannelType.GUILD_STORE: + default: + throw new HTTPError("Not yet supported"); + } + + if (!channel.permission_overwrites) channel.permission_overwrites = []; + // TODO: eagerly auto generate position of all guild channels + + channel = { + ...channel, + ...(!opts?.keepId && { id: Snowflake.generate() }), + created_at: new Date(), + position: (channel.type === ChannelType.UNHANDLED ? 0 : channel.position) || 0 + }; + + await Promise.all([ + OrmUtils.mergeDeep(new Channel(), channel).save(), + !opts?.skipEventEmit + ? emitEvent({ + event: "CHANNEL_CREATE", + data: channel, + guild_id: channel.guild_id + } as ChannelCreateEvent) + : Promise.resolve() + ]); + + return channel; + } + + static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) { + recipients = recipients.unique().filter((x) => x !== creator_user_id); + const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) }); + + // TODO: check config for max number of recipients + /** if you want to disallow note to self channels, uncomment the conditional below + if (otherRecipientsUsers.length !== recipients.length) { + throw new HTTPError("Recipient/s not found"); + } + **/ + + const type = recipients.length > 1 ? ChannelType.GROUP_DM : ChannelType.DM; + + let channel = null; + + const channelRecipients = [...recipients, creator_user_id]; + + const userRecipients = await Recipient.find({ + where: { user_id: creator_user_id }, + relations: ["channel", "channel.recipients"] + }); + + for (let ur of userRecipients) { + let re = ur.channel.recipients!.map((r) => r.user_id); + if (re.length === channelRecipients.length) { + if (containsAll(re, channelRecipients)) { + if (channel == null) { + channel = ur.channel; + ur = OrmUtils.mergeDeep(ur, { closed: false }); + await ur.save(); + } + } + } + } + + if (channel == null) { + name = trimSpecial(name); + + channel = await ( + OrmUtils.mergeDeep(new Channel(), { + name, + type, + owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server + created_at: new Date(), + last_message_id: null, + recipients: channelRecipients.map((x) => + OrmUtils.mergeDeep(new Recipient(), { + user_id: x, + closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) + }) + ) + }) as Channel + ).save(); + } + + const channel_dto = await DmChannelDTO.from(channel); + + if (type === ChannelType.GROUP_DM) { + for (let recipient of channel.recipients!) { + await emitEvent({ + event: "CHANNEL_CREATE", + data: channel_dto.excludedRecipients([recipient.user_id]), + user_id: recipient.user_id + }); + } + } else { + await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id }); + } + + if (recipients.length === 1) return channel_dto; + else return channel_dto.excludedRecipients([creator_user_id]); + } + + static async removeRecipientFromChannel(channel: Channel, user_id: string) { + await Recipient.delete({ channel_id: channel.id, user_id: user_id }); + channel.recipients = channel.recipients?.filter((r) => r.user_id !== user_id); + + if (channel.recipients?.length === 0) { + await Channel.deleteChannel(channel); + await emitEvent({ + event: "CHANNEL_DELETE", + data: await DmChannelDTO.from(channel, [user_id]), + user_id: user_id + }); + return; + } + + await emitEvent({ + event: "CHANNEL_DELETE", + data: await DmChannelDTO.from(channel, [user_id]), + user_id: user_id + }); + + //If the owner leave the server user is the new owner + if (channel.owner_id === user_id) { + channel.owner_id = "1"; // The channel is now owned by the server user + await emitEvent({ + event: "CHANNEL_UPDATE", + data: await DmChannelDTO.from(channel, [user_id]), + channel_id: channel.id + }); + } + + await channel.save(); + + await emitEvent({ + event: "CHANNEL_RECIPIENT_REMOVE", + data: { + channel_id: channel.id, + user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection }) + }, + channel_id: channel.id + } as ChannelRecipientRemoveEvent); + } + + static async deleteChannel(channel: Channel) { + await Message.delete({ channel_id: channel.id }); //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util + //TODO before deleting the channel we should check and delete other relations + await Channel.delete({ id: channel.id }); + } + + isDm() { + return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM; + } + + // Does the channel support sending messages ( eg categories do not ) + isWritable() { + const disallowedChannelTypes = [ChannelType.GUILD_CATEGORY, ChannelType.GUILD_STAGE_VOICE, ChannelType.VOICELESS_WHITEBOARD]; + return disallowedChannelTypes.indexOf(this.type) == -1; + } +} + +export interface ChannelPermissionOverwrite { + allow: string; + deny: string; + id: string; + type: ChannelPermissionOverwriteType; +} + +export enum ChannelPermissionOverwriteType { + role = 0, + member = 1, + group = 2 +} diff --git a/util/src/entities/ClientRelease.ts b/src/util/entities/ClientRelease.ts
index c5afd307..2723ab67 100644 --- a/util/src/entities/ClientRelease.ts +++ b/src/util/entities/ClientRelease.ts
@@ -1,4 +1,4 @@ -import { Column, Entity} from "typeorm"; +import { Column, Entity } from "typeorm"; import { BaseClass } from "./BaseClass"; @Entity("client_release") diff --git a/src/util/entities/Config.ts b/src/util/entities/Config.ts new file mode 100644
index 00000000..fc33bb65 --- /dev/null +++ b/src/util/entities/Config.ts
@@ -0,0 +1,11 @@ +import { Column, Entity } from "typeorm"; +import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass"; + +@Entity("config") +export class ConfigEntity extends BaseClassWithoutId { + @PrimaryIdColumn() + key: string; + + @Column({ type: "simple-json", nullable: true }) + value: number | boolean | null | string | undefined; +} diff --git a/util/src/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts
index 09ae30ab..018b3995 100644 --- a/util/src/entities/ConnectedAccount.ts +++ b/src/util/entities/ConnectedAccount.ts
@@ -12,7 +12,7 @@ export class ConnectedAccount extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; diff --git a/util/src/entities/Emoji.ts b/src/util/entities/Emoji.ts
index a3615b7d..a2552995 100644 --- a/util/src/entities/Emoji.ts +++ b/src/util/entities/Emoji.ts
@@ -2,7 +2,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { User } from "."; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; -import { Role } from "./Role"; @Entity("emojis") export class Emoji extends BaseClass { @@ -17,7 +16,7 @@ export class Emoji extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; @@ -40,7 +39,7 @@ export class Emoji extends BaseClass { @Column({ type: "simple-array" }) roles: string[]; // roles this emoji is whitelisted to (new discord feature?) - + @Column({ type: "simple-array", nullable: true }) groups: string[]; // user groups this emoji is whitelisted to (Fosscord extension) } diff --git a/src/util/entities/Encryption.ts b/src/util/entities/Encryption.ts new file mode 100644
index 00000000..43f02962 --- /dev/null +++ b/src/util/entities/Encryption.ts
@@ -0,0 +1,25 @@ +import { Column, Entity } from "typeorm"; +import { Snowflake } from "../util"; +import { BitField } from "../util/BitField"; +import { BaseClass } from "./BaseClass"; + +@Entity("security_settings") +export class SecuritySettings extends BaseClass { + @Column({ nullable: true }) + guild_id: Snowflake; + + @Column({ nullable: true }) + channel_id: Snowflake; + + @Column() + encryption_permission_mask: BitField; + + @Column() + allowed_algorithms: string[]; + + @Column() + current_algorithm: string; + + @Column({ nullable: true }) + used_since_message: Snowflake; +} diff --git a/util/src/entities/Group.ts b/src/util/entities/Group.ts
index b24d38cf..23aaabf2 100644 --- a/util/src/entities/Group.ts +++ b/src/util/entities/Group.ts
@@ -1,11 +1,11 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Column, Entity } from "typeorm"; import { BaseClass } from "./BaseClass"; @Entity("groups") export class UserGroup extends BaseClass { - @Column({ nullable: true }) - parent?: BigInt; + @Column({ nullable: true }) + parent?: BigInt; @Column() color: number; @@ -13,7 +13,7 @@ export class UserGroup extends BaseClass { @Column() hoist: boolean; - @Column() + @Column() mentionable: boolean; @Column() diff --git a/util/src/entities/Guild.ts b/src/util/entities/Guild.ts
index 70bb41c5..015c6d04 100644 --- a/util/src/entities/Guild.ts +++ b/src/util/entities/Guild.ts
@@ -1,5 +1,6 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToMany, OneToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; import { Config, handleFile, Snowflake } from ".."; +import { OrmUtils } from "../util/imports/OrmUtils"; import { Ban } from "./Ban"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; @@ -31,15 +32,7 @@ import { Webhook } from "./Webhook"; // "Gacha" // ], -export const PublicGuildRelations = [ - "channels", - "emojis", - "members", - "roles", - "stickers", - "voice_states", - "members.user", -]; +export const PublicGuildRelations = ["channels", "emojis", "members", "roles", "stickers", "voice_states", "members.user"]; @Entity("guilds") export class Guild extends BaseClass { @@ -52,7 +45,7 @@ export class Guild extends BaseClass { afk_channel?: Channel; @Column({ nullable: true }) - afk_timeout?: number; + afk_timeout?: number = Config.get().defaults.guild.afkTimeout; // * commented out -> use owner instead // application id of the guild creator if it is bot-created @@ -62,7 +55,7 @@ export class Guild extends BaseClass { @JoinColumn({ name: "ban_ids" }) @OneToMany(() => Ban, (ban: Ban) => ban.guild, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) bans: Ban[]; @@ -70,7 +63,7 @@ export class Guild extends BaseClass { banner?: string; @Column({ nullable: true }) - default_message_notifications?: number; + default_message_notifications?: number = Config.get().defaults.guild.defaultMessageNotifications; @Column({ nullable: true }) description?: string; @@ -79,7 +72,7 @@ export class Guild extends BaseClass { discovery_splash?: string; @Column({ nullable: true }) - explicit_content_filter?: number; + explicit_content_filter?: number = Config.get().defaults.guild.explicitContentFilter; @Column({ type: "simple-array" }) features: string[]; //TODO use enum @@ -95,24 +88,24 @@ export class Guild extends BaseClass { large?: boolean; @Column({ nullable: true }) - max_members?: number; // e.g. default 100.000 + max_members?: number = Config.get().limits.guild.maxMembers; // e.g. default 100.000 @Column({ nullable: true }) - max_presences?: number; + max_presences?: number = Config.get().defaults.guild.maxPresences; @Column({ nullable: true }) - max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching + max_video_channel_users?: number = Config.get().defaults.guild.maxVideoChannelUsers; // ? default: 25, is this max 25 streaming or watching @Column({ nullable: true }) - member_count?: number; + member_count?: number = 0; @Column({ nullable: true }) - presence_count?: number; // users online + presence_count?: number = 0; // users online @OneToMany(() => Member, (member: Member) => member.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) members: Member[]; @@ -120,14 +113,14 @@ export class Guild extends BaseClass { @OneToMany(() => Role, (role: Role) => role.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) roles: Role[]; @JoinColumn({ name: "channel_ids" }) @OneToMany(() => Channel, (channel: Channel) => channel.guild, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) channels: Channel[]; @@ -143,7 +136,7 @@ export class Guild extends BaseClass { @OneToMany(() => Emoji, (emoji: Emoji) => emoji.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) emojis: Emoji[]; @@ -151,7 +144,7 @@ export class Guild extends BaseClass { @OneToMany(() => Sticker, (sticker: Sticker) => sticker.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) stickers: Sticker[]; @@ -159,7 +152,7 @@ export class Guild extends BaseClass { @OneToMany(() => Invite, (invite: Invite) => invite.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) invites: Invite[]; @@ -167,7 +160,7 @@ export class Guild extends BaseClass { @OneToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) voice_states: VoiceState[]; @@ -175,7 +168,7 @@ export class Guild extends BaseClass { @OneToMany(() => Webhook, (webhook: Webhook) => webhook.guild, { cascade: true, orphanedRowAction: "delete", - onDelete: "CASCADE", + onDelete: "CASCADE" }) webhooks: Webhook[]; @@ -269,7 +262,7 @@ export class Guild extends BaseClass { @Column({ nullable: true }) nsfw?: boolean; - + // TODO: nested guilds @Column({ nullable: true }) parent?: string; @@ -277,15 +270,14 @@ export class Guild extends BaseClass { // only for developer portal permissions?: number; - static async createGuild(body: { - name?: string; - icon?: string | null; - owner_id?: string; - channels?: Partial<Channel>[]; - }) { + //new guild settings, 11/08/2022: + @Column({ nullable: true }) + premium_progress_bar_enabled: boolean = false; + + static async createGuild(body: { name?: string; icon?: string | null; owner_id?: string; channels?: Partial<Channel>[] }) { const guild_id = Snowflake.generate(); - const guild = await new Guild({ + const guild: Guild = OrmUtils.mergeDeep(new Guild(), { name: body.name || "Fosscord", icon: await handleFile(`/icons/${guild_id}`, body.icon as string), region: Config.get().regions.default, @@ -313,14 +305,15 @@ export class Guild extends BaseClass { welcome_screen: { enabled: false, description: "Fill in your description", - welcome_channels: [], + welcome_channels: [] }, - widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions - }).save(); + widget_enabled: true // NB: don't set it as false to prevent artificial restrictions + }); + await guild.save(); // we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error // TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage - await new Role({ + let role: Role = OrmUtils.mergeDeep(new Role(), { id: guild_id, guild_id: guild_id, color: 0, @@ -333,7 +326,8 @@ export class Guild extends BaseClass { position: 0, icon: null, unicode_emoji: null - }).save(); + }); + await role.save(); if (!body.channels || !body.channels.length) body.channels = [{ id: "01", type: 0, name: "general" }]; @@ -346,15 +340,15 @@ export class Guild extends BaseClass { }); for (const channel of body.channels?.sort((a, b) => (a.parent_id ? 1 : -1))) { - var id = ids.get(channel.id) || Snowflake.generate(); + let id = ids.get(channel.id) || Snowflake.generate(); - var parent_id = ids.get(channel.parent_id); + let parent_id = ids.get(channel.parent_id); await Channel.createChannel({ ...channel, guild_id, id, parent_id }, body.owner_id, { keepId: true, skipExistsCheck: true, skipPermissionCheck: true, - skipEventEmit: true, + skipEventEmit: true }); } diff --git a/util/src/entities/Invite.ts b/src/util/entities/Invite.ts
index 6ac64ddc..f6ba85d7 100644 --- a/util/src/entities/Invite.ts +++ b/src/util/entities/Invite.ts
@@ -1,8 +1,9 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId, PrimaryColumn } from "typeorm"; -import { Member } from "./Member"; +import { random } from "@fosscord/api"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, RelationId } from "typeorm"; import { BaseClassWithoutId } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; +import { Member } from "./Member"; import { User } from "./User"; export const PublicInviteRelation = ["inviter", "guild", "channel"]; @@ -10,13 +11,13 @@ export const PublicInviteRelation = ["inviter", "guild", "channel"]; @Entity("invites") export class Invite extends BaseClassWithoutId { @PrimaryColumn() - code: string; + code: string = random(); @Column() - temporary: boolean; + temporary: boolean = true; @Column() - uses: number; + uses: number = 0; @Column() max_uses: number; @@ -25,7 +26,7 @@ export class Invite extends BaseClassWithoutId { max_age: number; @Column() - created_at: Date; + created_at: Date = new Date(); @Column() expires_at: Date; @@ -36,7 +37,7 @@ export class Invite extends BaseClassWithoutId { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; @@ -46,7 +47,7 @@ export class Invite extends BaseClassWithoutId { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: Channel; @@ -55,7 +56,9 @@ export class Invite extends BaseClassWithoutId { inviter_id: string; @JoinColumn({ name: "inviter_id" }) - @ManyToOne(() => User) + @ManyToOne(() => User, { + onDelete: "CASCADE" + }) inviter: User; @Column({ nullable: true }) @@ -64,7 +67,7 @@ export class Invite extends BaseClassWithoutId { @JoinColumn({ name: "target_user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) target_user?: string; // could be used for "User specific invites" https://github.com/fosscord/fosscord/issues/62 @@ -75,7 +78,7 @@ export class Invite extends BaseClassWithoutId { vanity_url?: boolean; static async joinGuild(user_id: string, code: string) { - const invite = await Invite.findOneOrFail({ code }); + const invite = await Invite.findOneOrFail({ where: { code } }); if (invite.uses++ >= invite.max_uses && invite.max_uses !== 0) await Invite.delete({ code }); else await invite.save(); diff --git a/util/src/entities/Member.ts b/src/util/entities/Member.ts
index a6798a7c..f67ec02c 100644 --- a/util/src/entities/Member.ts +++ b/src/util/entities/Member.ts
@@ -1,32 +1,14 @@ -import { PublicUser, User } from "./User"; -import { Message } from "./Message"; -import { BaseClass } from "./BaseClass"; -import { - Column, - Entity, - Index, - JoinColumn, - JoinTable, - ManyToMany, - ManyToOne, - PrimaryGeneratedColumn, - RelationId, -} from "typeorm"; -import { Guild } from "./Guild"; +import { Column, Entity, Index, JoinColumn, JoinTable, ManyToMany, ManyToOne, PrimaryGeneratedColumn, RelationId } from "typeorm"; +import { Ban, PublicGuildRelations, Message } from "."; +import { GuildCreateEvent, GuildDeleteEvent, GuildMemberAddEvent, GuildMemberRemoveEvent, GuildMemberUpdateEvent, MessageCreateEvent } from "../interfaces"; import { Config, emitEvent } from "../util"; -import { - GuildCreateEvent, - GuildDeleteEvent, - GuildMemberAddEvent, - GuildMemberRemoveEvent, - GuildMemberUpdateEvent, - MessageCreateEvent, -} from "../interfaces"; -import { HTTPError } from "lambert-server"; -import { Role } from "./Role"; -import { BaseClassWithoutId } from "./BaseClass"; -import { Ban, PublicGuildRelations } from "."; import { DiscordApiErrors } from "../util/Constants"; +import { HTTPError } from "../util/imports/HTTPError"; +import { OrmUtils } from "../util/imports/OrmUtils"; +import { BaseClassWithoutId } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Role } from "./Role"; +import { PublicUser, User } from "./User"; export const MemberPrivateProjection: (keyof Member)[] = [ "id", @@ -41,7 +23,7 @@ export const MemberPrivateProjection: (keyof Member)[] = [ "premium_since", "roles", "settings", - "user", + "user" ]; @Entity("members") @@ -56,7 +38,7 @@ export class Member extends BaseClassWithoutId { @JoinColumn({ name: "id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; @@ -66,7 +48,7 @@ export class Member extends BaseClassWithoutId { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; @@ -78,8 +60,8 @@ export class Member extends BaseClassWithoutId { joinColumn: { name: "index", referencedColumnName: "index" }, inverseJoinColumn: { name: "role_id", - referencedColumnName: "id", - }, + referencedColumnName: "id" + } }) @ManyToMany(() => Role, { cascade: true }) roles: Role[]; @@ -87,8 +69,8 @@ export class Member extends BaseClassWithoutId { @Column() joined_at: Date; - @Column({ type: "bigint", nullable: true }) - premium_since?: number; + @Column({ nullable: true }) + premium_since?: Date; @Column() deaf: boolean; @@ -119,35 +101,37 @@ export class Member extends BaseClassWithoutId { // read_state: ReadState; static async IsInGuildOrFail(user_id: string, guild_id: string) { - if (await Member.count({ id: user_id, guild: { id: guild_id } })) return true; + if (await Member.count({ where: { id: user_id, guild: { id: guild_id } } })) return true; throw new HTTPError("You are not member of this guild", 403); } static async removeFromGuild(user_id: string, guild_id: string) { - const guild = await Guild.findOneOrFail({ select: ["owner_id"], where: { id: guild_id } }); + const guild = await Guild.findOneOrFail({ select: ["owner_id", "member_count"], where: { id: guild_id } }); if (guild.owner_id === user_id) throw new Error("The owner cannot be removed of the guild"); const member = await Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user"] }); // use promise all to execute all promises at the same time -> save time + //TODO: check for bugs + if (guild.member_count) guild.member_count--; return Promise.all([ Member.delete({ id: user_id, - guild_id, + guild_id }), - Guild.decrement({ id: guild_id }, "member_count", -1), + //Guild.decrement({ id: guild_id }, "member_count", -1), emitEvent({ event: "GUILD_DELETE", data: { - id: guild_id, + id: guild_id }, - user_id: user_id, + user_id: user_id } as GuildDeleteEvent), emitEvent({ event: "GUILD_MEMBER_REMOVE", data: { guild_id, user: member.user }, - guild_id, - } as GuildMemberRemoveEvent), + guild_id + } as GuildMemberRemoveEvent) ]); } @@ -157,11 +141,11 @@ export class Member extends BaseClassWithoutId { Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user", "roles"], // we don't want to load the role objects just the ids - select: ["index", "roles.id"], + select: ["index"] }), - Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }), + Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }) ]); - member.roles.push(new Role({ id: role_id })); + member.roles.push(OrmUtils.mergeDeep(new Role(), { id: role_id })); await Promise.all([ member.save(), @@ -170,10 +154,10 @@ export class Member extends BaseClassWithoutId { data: { guild_id, user: member.user, - roles: member.roles.map((x) => x.id), + roles: member.roles.map((x) => x.id) }, - guild_id, - } as GuildMemberUpdateEvent), + guild_id + } as GuildMemberUpdateEvent) ]); } @@ -183,9 +167,9 @@ export class Member extends BaseClassWithoutId { Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user", "roles"], // we don't want to load the role objects just the ids - select: ["roles.id", "index"], + select: ["index"] }), - await Role.findOneOrFail({ id: role_id, guild_id }), + await Role.findOneOrFail({ where: { id: role_id, guild_id } }) ]); member.roles = member.roles.filter((x) => x.id == role_id); @@ -196,10 +180,10 @@ export class Member extends BaseClassWithoutId { data: { guild_id, user: member.user, - roles: member.roles.map((x) => x.id), + roles: member.roles.map((x) => x.id) }, - guild_id, - } as GuildMemberUpdateEvent), + guild_id + } as GuildMemberUpdateEvent) ]); } @@ -207,9 +191,9 @@ export class Member extends BaseClassWithoutId { const member = await Member.findOneOrFail({ where: { id: user_id, - guild_id, + guild_id }, - relations: ["user"], + relations: ["user"] }); member.nick = nickname; @@ -221,10 +205,10 @@ export class Member extends BaseClassWithoutId { data: { guild_id, user: member.user, - nick: nickname, + nick: nickname }, - guild_id, - } as GuildMemberUpdateEvent), + guild_id + } as GuildMemberUpdateEvent) ]); } @@ -235,19 +219,19 @@ export class Member extends BaseClassWithoutId { throw DiscordApiErrors.USER_BANNED; } const { maxGuilds } = Config.get().limits.user; - const guild_count = await Member.count({ id: user_id }); + const guild_count = await Member.count({ where: { id: user_id } }); if (guild_count >= maxGuilds) { throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403); } const guild = await Guild.findOneOrFail({ where: { - id: guild_id, + id: guild_id }, - relations: [ ...PublicGuildRelations, "system_channel" ], + relations: PublicGuildRelations }); - if (await Member.count({ id: user.id, guild: { id: guild_id } })) + if (await Member.count({ where: { id: user.id, guild: { id: guild_id } } })) throw new HTTPError("You are already a member of this guild", 400); const member = { @@ -256,16 +240,17 @@ export class Member extends BaseClassWithoutId { nick: undefined, roles: [guild_id], // @everyone role joined_at: new Date(), - premium_since: (new Date()).getTime(), + premium_since: null, deaf: false, mute: false, - pending: false, + pending: false }; - + //TODO: check for bugs + if (guild.member_count) guild.member_count++; await Promise.all([ - new Member({ + OrmUtils.mergeDeep(new Member(), { ...member, - roles: [new Role({ id: guild_id })], + roles: [OrmUtils.mergeDeep(new Role(), { id: guild_id })], // read_state: {}, settings: { channel_overrides: [], @@ -274,19 +259,19 @@ export class Member extends BaseClassWithoutId { muted: false, suppress_everyone: false, suppress_roles: false, - version: 0, - }, + version: 0 + } // Member.save is needed because else the roles relations wouldn't be updated }).save(), - Guild.increment({ id: guild_id }, "member_count", 1), + //Guild.increment({ id: guild_id }, "member_count", 1), emitEvent({ event: "GUILD_MEMBER_ADD", data: { ...member, user, - guild_id, + guild_id }, - guild_id, + guild_id } as GuildMemberAddEvent), emitEvent({ event: "GUILD_CREATE", @@ -299,15 +284,15 @@ export class Member extends BaseClassWithoutId { joined_at: member.joined_at, presences: [], stage_instances: [], - threads: [], + threads: [] }, - user_id, - } as GuildCreateEvent), + user_id + } as GuildCreateEvent) ]); if (guild.system_channel_id) { // send welcome message - const message = new Message({ + const message = OrmUtils.mergeDeep(new Message(), { type: 7, guild_id: guild.id, channel_id: guild.system_channel_id, @@ -349,16 +334,7 @@ export interface MuteConfig { selected_time_window: number; } -export type PublicMemberKeys = - | "id" - | "guild_id" - | "nick" - | "roles" - | "joined_at" - | "pending" - | "deaf" - | "mute" - | "premium_since"; +export type PublicMemberKeys = "id" | "guild_id" | "nick" | "roles" | "joined_at" | "pending" | "deaf" | "mute" | "premium_since"; export const PublicMemberProjection: PublicMemberKeys[] = [ "id", @@ -369,7 +345,7 @@ export const PublicMemberProjection: PublicMemberKeys[] = [ "pending", "deaf", "mute", - "premium_since", + "premium_since" ]; // @ts-ignore diff --git a/util/src/entities/Message.ts b/src/util/entities/Message.ts
index e18cf691..8122b532 100644 --- a/util/src/entities/Message.ts +++ b/src/util/entities/Message.ts
@@ -1,29 +1,15 @@ -import { User } from "./User"; -import { Member } from "./Member"; -import { Role } from "./Role"; -import { Channel } from "./Channel"; +import { Column, CreateDateColumn, Entity, Index, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToMany, RelationId } from "typeorm"; import { InteractionType } from "../interfaces/Interaction"; import { Application } from "./Application"; -import { - Column, - CreateDateColumn, - Entity, - FindConditions, - Index, - JoinColumn, - JoinTable, - ManyToMany, - ManyToOne, - OneToMany, - RelationId, - RemoveOptions, - UpdateDateColumn, -} from "typeorm"; +import { Attachment } from "./Attachment"; import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; import { Guild } from "./Guild"; -import { Webhook } from "./Webhook"; +import { Member } from "./Member"; +import { Role } from "./Role"; import { Sticker } from "./Sticker"; -import { Attachment } from "./Attachment"; +import { User } from "./User"; +import { Webhook } from "./Webhook"; export enum MessageType { DEFAULT = 0, @@ -63,7 +49,7 @@ export class Message extends BaseClass { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: Channel; @@ -73,7 +59,7 @@ export class Message extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild?: Guild; @@ -84,7 +70,7 @@ export class Message extends BaseClass { @JoinColumn({ name: "author_id", referencedColumnName: "id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) author?: User; @@ -94,7 +80,7 @@ export class Message extends BaseClass { @JoinColumn({ name: "member_id", referencedColumnName: "id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) member?: Member; @@ -148,7 +134,7 @@ export class Message extends BaseClass { @OneToMany(() => Attachment, (attachment: Attachment) => attachment.message, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) attachments?: Attachment[]; @@ -213,7 +199,7 @@ export interface MessageComponent { export enum MessageComponentType { Script = 0, // self command script ActionRow = 1, - Button = 2, + Button = 2 } export interface Embed { @@ -254,7 +240,7 @@ export enum EmbedType { video = "video", gifv = "gifv", article = "article", - link = "link", + link = "link" } export interface EmbedImage { diff --git a/util/src/entities/Migration.ts b/src/util/entities/Migration.ts
index 3f39ae72..626ec429 100644 --- a/util/src/entities/Migration.ts +++ b/src/util/entities/Migration.ts
@@ -1,9 +1,7 @@ import { Column, Entity, ObjectIdColumn, PrimaryGeneratedColumn } from "typeorm"; import { BaseClassWithoutId } from "."; -export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith("mongodb") - ? ObjectIdColumn - : PrimaryGeneratedColumn; +export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryGeneratedColumn; @Entity("migrations") export class Migration extends BaseClassWithoutId { diff --git a/src/util/entities/Note.ts b/src/util/entities/Note.ts new file mode 100644
index 00000000..b3ac45ee --- /dev/null +++ b/src/util/entities/Note.ts
@@ -0,0 +1,18 @@ +import { Column, Entity, JoinColumn, ManyToOne, Unique } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; + +@Entity("notes") +@Unique(["owner", "target"]) +export class Note extends BaseClass { + @JoinColumn({ name: "owner_id" }) + @ManyToOne(() => User, { onDelete: "CASCADE" }) + owner: User; + + @JoinColumn({ name: "target_id" }) + @ManyToOne(() => User, { onDelete: "CASCADE" }) + target: User; + + @Column() + content: string; +} diff --git a/util/src/entities/RateLimit.ts b/src/util/entities/RateLimit.ts
index f5916f6b..f5916f6b 100644 --- a/util/src/entities/RateLimit.ts +++ b/src/util/entities/RateLimit.ts
diff --git a/util/src/entities/ReadState.ts b/src/util/entities/ReadState.ts
index b915573b..77d2c08a 100644 --- a/util/src/entities/ReadState.ts +++ b/src/util/entities/ReadState.ts
@@ -1,7 +1,6 @@ import { Column, Entity, Index, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; -import { Message } from "./Message"; import { User } from "./User"; // for read receipts @@ -17,7 +16,7 @@ export class ReadState extends BaseClass { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: Channel; @@ -27,14 +26,14 @@ export class ReadState extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; // fully read marker @Column({ nullable: true }) - last_message_id: string; - + last_message_id: string; + // public read receipt @Column({ nullable: true }) public_ack: string; diff --git a/util/src/entities/Recipient.ts b/src/util/entities/Recipient.ts
index a945f938..fc9e629b 100644 --- a/util/src/entities/Recipient.ts +++ b/src/util/entities/Recipient.ts
@@ -9,7 +9,7 @@ export class Recipient extends BaseClass { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => require("./Channel").Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: import("./Channel").Channel; @@ -19,7 +19,7 @@ export class Recipient extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => require("./User").User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: import("./User").User; diff --git a/util/src/entities/Relationship.ts b/src/util/entities/Relationship.ts
index c3592c76..b55d9e64 100644 --- a/util/src/entities/Relationship.ts +++ b/src/util/entities/Relationship.ts
@@ -6,7 +6,7 @@ export enum RelationshipType { outgoing = 4, incoming = 3, blocked = 2, - friends = 1, + friends = 1 } @Entity("relationships") @@ -18,7 +18,7 @@ export class Relationship extends BaseClass { @JoinColumn({ name: "from_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) from: User; @@ -28,7 +28,7 @@ export class Relationship extends BaseClass { @JoinColumn({ name: "to_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) to: User; @@ -43,7 +43,7 @@ export class Relationship extends BaseClass { id: this.to?.id || this.to_id, type: this.type, nickname: this.nickname, - user: this.to?.toPublicUser(), + user: this.to?.toPublicUser() }; } } diff --git a/util/src/entities/Role.ts b/src/util/entities/Role.ts
index 4b721b5b..b1fd9bb1 100644 --- a/util/src/entities/Role.ts +++ b/src/util/entities/Role.ts
@@ -11,7 +11,7 @@ export class Role extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; diff --git a/util/src/entities/Session.ts b/src/util/entities/Session.ts
index 969efa89..0cb4c309 100644 --- a/util/src/entities/Session.ts +++ b/src/util/entities/Session.ts
@@ -1,8 +1,8 @@ -import { User } from "./User"; -import { BaseClass } from "./BaseClass"; import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; -import { Status } from "../interfaces/Status"; import { Activity } from "../interfaces/Activity"; +import { Status } from "../interfaces/Status"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; //TODO we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them @@ -14,7 +14,7 @@ export class Session extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; @@ -37,10 +37,4 @@ export class Session extends BaseClass { status: Status; //TODO enum } -export const PrivateSessionProjection: (keyof Session)[] = [ - "user_id", - "session_id", - "activities", - "client_info", - "status", -]; +export const PrivateSessionProjection: (keyof Session)[] = ["user_id", "session_id", "activities", "client_info", "status"]; diff --git a/util/src/entities/Sticker.ts b/src/util/entities/Sticker.ts
index 37bc6fbe..69836e62 100644 --- a/util/src/entities/Sticker.ts +++ b/src/util/entities/Sticker.ts
@@ -1,18 +1,18 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; -import { User } from "./User"; import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; +import { User } from "./User"; export enum StickerType { STANDARD = 1, - GUILD = 2, + GUILD = 2 } export enum StickerFormatType { GIF = 0, // gif is a custom format type and not in discord spec PNG = 1, APNG = 2, - LOTTIE = 3, + LOTTIE = 3 } @Entity("stickers") @@ -36,7 +36,7 @@ export class Sticker extends BaseClass { @JoinColumn({ name: "pack_id" }) @ManyToOne(() => require("./StickerPack").StickerPack, { onDelete: "CASCADE", - nullable: true, + nullable: true }) pack: import("./StickerPack").StickerPack; @@ -45,7 +45,7 @@ export class Sticker extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild?: Guild; @@ -54,7 +54,7 @@ export class Sticker extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user?: User; diff --git a/util/src/entities/StickerPack.ts b/src/util/entities/StickerPack.ts
index ec8c69a2..4619af34 100644 --- a/util/src/entities/StickerPack.ts +++ b/src/util/entities/StickerPack.ts
@@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; import { Sticker } from "."; import { BaseClass } from "./BaseClass"; @@ -15,7 +15,7 @@ export class StickerPack extends BaseClass { @OneToMany(() => Sticker, (sticker: Sticker) => sticker.pack, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) stickers: Sticker[]; diff --git a/util/src/entities/Team.ts b/src/util/entities/Team.ts
index 22140b7f..1d2d7002 100644 --- a/util/src/entities/Team.ts +++ b/src/util/entities/Team.ts
@@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToMany, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { TeamMember } from "./TeamMember"; import { User } from "./User"; @@ -10,7 +10,7 @@ export class Team extends BaseClass { @JoinColumn({ name: "member_ids" }) @OneToMany(() => TeamMember, (member: TeamMember) => member.team, { - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) members: TeamMember[]; diff --git a/util/src/entities/TeamMember.ts b/src/util/entities/TeamMember.ts
index b726e1e8..d11ebf95 100644 --- a/util/src/entities/TeamMember.ts +++ b/src/util/entities/TeamMember.ts
@@ -4,7 +4,7 @@ import { User } from "./User"; export enum TeamMemberState { INVITED = 1, - ACCEPTED = 2, + ACCEPTED = 2 } @Entity("team_members") @@ -21,7 +21,7 @@ export class TeamMember extends BaseClass { @JoinColumn({ name: "team_id" }) @ManyToOne(() => require("./Team").Team, (team: import("./Team").Team) => team.members, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) team: import("./Team").Team; @@ -31,7 +31,7 @@ export class TeamMember extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; } diff --git a/util/src/entities/Template.ts b/src/util/entities/Template.ts
index 1d952283..1d952283 100644 --- a/util/src/entities/Template.ts +++ b/src/util/entities/Template.ts
diff --git a/util/src/entities/User.ts b/src/util/entities/User.ts
index 9b1c494e..1237b676 100644 --- a/util/src/entities/User.ts +++ b/src/util/entities/User.ts
@@ -1,10 +1,11 @@ -import { Column, Entity, FindOneOptions, JoinColumn, ManyToMany, OneToMany, RelationId } from "typeorm"; -import { BaseClass } from "./BaseClass"; +import { Column, Entity, FindOneOptions, FindOptionsSelectByString, JoinColumn, OneToMany, OneToOne } from "typeorm"; +import { Member, Session, UserSettings } from "."; +import { Config, FieldErrors, Snowflake, trimSpecial } from ".."; import { BitField } from "../util/BitField"; -import { Relationship } from "./Relationship"; +import { OrmUtils } from "../util/imports/OrmUtils"; +import { BaseClass } from "./BaseClass"; import { ConnectedAccount } from "./ConnectedAccount"; -import { Config, FieldErrors, Snowflake, trimSpecial } from ".."; -import { Member, Session } from "."; +import { Relationship } from "./Relationship"; export enum PublicUserEnum { username, @@ -16,7 +17,7 @@ export enum PublicUserEnum { banner, bio, bot, - premium_since, + premium_since } export type PublicUserKeys = keyof typeof PublicUserEnum; @@ -30,17 +31,15 @@ export enum PrivateUserEnum { premium, premium_type, disabled, - settings, + settings // locale } export type PrivateUserKeys = keyof typeof PrivateUserEnum | PublicUserKeys; -export const PublicUserProjection = Object.values(PublicUserEnum).filter( - (x) => typeof x === "string" -) as PublicUserKeys[]; +export const PublicUserProjection = Object.values(PublicUserEnum).filter((x) => typeof x === "string") as PublicUserKeys[]; export const PrivateUserProjection = [ ...PublicUserProjection, - ...Object.values(PrivateUserEnum).filter((x) => typeof x === "string"), + ...Object.values(PrivateUserEnum).filter((x) => typeof x === "string") ] as PrivateUserKeys[]; // Private user data that should never get sent to the client @@ -82,58 +81,64 @@ export class User extends BaseClass { phone?: string; // phone number of the user @Column({ select: false }) - desktop: boolean; // if the user has desktop app installed + desktop: boolean = false; // if the user has desktop app installed @Column({ select: false }) - mobile: boolean; // if the user has mobile app installed + mobile: boolean = false; // if the user has mobile app installed @Column() - premium: boolean; // if user bought individual premium - - @Column() - premium_type: number; // individual premium level + premium: boolean = Config.get().defaults.user.premium; // if user bought individual premium @Column() - bot: boolean; // if user is bot + premium_type: number = Config.get().defaults.user.premium_type; // individual premium level @Column() + bot: boolean = false; // if user is bot + + @Column({ nullable: true }) bio: string; // short description of the user (max 190 chars -> should be configurable) @Column() - system: boolean; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author + system: boolean = false; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author @Column({ select: false }) - nsfw_allowed: boolean; // if the user can do age-restricted actions (NSFW channels/guilds/commands) - - @Column({ select: false }) + nsfw_allowed: boolean = true; // if the user can do age-restricted actions (NSFW channels/guilds/commands) // TODO: depending on age + + @Column({ select: false, nullable: true }) mfa_enabled: boolean; // if multi factor authentication is enabled + @Column({ select: false, nullable: true }) + totp_secret?: string; + + @Column({ nullable: true, select: false }) + totp_last_ticket?: string; + @Column() - created_at: Date; // registration date + created_at: Date = new Date(); // registration date @Column({ nullable: true }) - premium_since: Date; // premium date + premium_since: Date = new Date(); // premium date @Column({ select: false }) - verified: boolean; // if the user is offically verified + verified: boolean = Config.get().defaults.user.verified; // if the user is offically verified @Column() - disabled: boolean; // if the account is disabled + disabled: boolean = false; // if the account is disabled @Column() - deleted: boolean; // if the user was deleted + deleted: boolean = false; // if the user was deleted @Column({ nullable: true, select: false }) email?: string; // email of the user @Column() - flags: string; // UserFlags + flags: string = "0"; // UserFlags // TODO: generate @Column() - public_flags: number; + public_flags: number = 0; @Column({ type: "bigint" }) - rights: string; // Rights + rights: string = Config.get().register.defaultRights; // Rights @OneToMany(() => Session, (session: Session) => session.user) sessions: Session[]; @@ -141,14 +146,14 @@ export class User extends BaseClass { @JoinColumn({ name: "relationship_ids" }) @OneToMany(() => Relationship, (relationship: Relationship) => relationship.from, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) relationships: Relationship[]; @JoinColumn({ name: "connected_account_ids" }) @OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.user, { cascade: true, - orphanedRowAction: "delete", + orphanedRowAction: "delete" }) connected_accounts: ConnectedAccount[]; @@ -159,17 +164,29 @@ export class User extends BaseClass { }; @Column({ type: "simple-array", select: false }) - fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts + fingerprints: string[] = []; // array of fingerprints -> used to prevent multiple accounts - @Column({ type: "simple-json", select: false }) + @OneToOne(() => UserSettings, { + cascade: true, + orphanedRowAction: "delete", + eager: false + }) + @JoinColumn() settings: UserSettings; - + // workaround to prevent fossord-unaware clients from deleting settings not used by them @Column({ type: "simple-json", select: false }) - extended_settings: string; + extended_settings: string = "{}"; @Column({ type: "simple-json" }) - notes: { [key: string]: string }; //key is ID of user + notes: { [key: string]: string } = {}; //key is ID of user + + async save(): Promise<any> { + if (!this.settings) this.settings = new UserSettings(); + this.settings.id = this.id; + //await this.settings.save(); + return super.save(); + } toPublicUser() { const user: any = {}; @@ -180,19 +197,17 @@ export class User extends BaseClass { } static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) { - return await User.findOneOrFail( - { id: user_id }, - { - ...opts, - select: [...PublicUserProjection, ...(opts?.select || [])], - } - ); + return await User.findOneOrFail({ + where: { id: user_id }, + select: [...PublicUserProjection, ...((opts?.select as FindOptionsSelectByString<User>) || [])], + ...opts + }); } - private static async generateDiscriminator(username: string): Promise<string | undefined> { + public static async generateDiscriminator(username: string): Promise<string | undefined> { if (Config.get().register.incrementingDiscriminators) { // discriminator will be incrementally generated - + // First we need to figure out the currently highest discrimnator for the given username and then increment it const users = await User.find({ where: { username }, select: ["discriminator"] }); const highestDiscriminator = Math.max(0, ...users.map((u) => Number(u.discriminator))); @@ -223,7 +238,7 @@ export class User extends BaseClass { username, password, date_of_birth, - req, + req }: { username: string; password?: string; @@ -240,48 +255,30 @@ export class User extends BaseClass { throw FieldErrors({ username: { code: "USERNAME_TOO_MANY_USERS", - message: req.t("auth:register.USERNAME_TOO_MANY_USERS"), - }, + message: req?.t("auth:register.USERNAME_TOO_MANY_USERS") + } }); } // TODO: save date_of_birth // appearently discord doesn't save the date of birth and just calculate if nsfw is allowed // if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false - const language = req.language === "en" ? "en-US" : req.language || "en-US"; + const language = req?.language === "en" ? "en-US" : req?.language || "en-US"; - const user = new User({ - created_at: new Date(), + const user = OrmUtils.mergeDeep(new User(), { + //required: username: username, discriminator, id: Snowflake.generate(), - bot: false, - system: false, - premium_since: new Date(), - desktop: false, - mobile: false, - premium: true, - premium_type: 2, - bio: "", - mfa_enabled: false, - verified: true, - disabled: false, - deleted: false, email: email, - rights: "0", // TODO: grant rights correctly, as 0 actually stands for no rights at all - nsfw_allowed: true, // TODO: depending on age - public_flags: "0", - flags: "0", // TODO: generate data: { hash: password, - valid_tokens_since: new Date(), + valid_tokens_since: new Date() }, - settings: { ...defaultSettings, locale: language }, - extended_settings: {}, - fingerprints: [], - notes: {}, + settings: { ...new UserSettings(), locale: language } }); + //await (user.settings as UserSettings).save(); await user.save(); setImmediate(async () => { @@ -296,85 +293,6 @@ export class User extends BaseClass { } } -export const defaultSettings: UserSettings = { - afk_timeout: 3600, - allow_accessibility_detection: true, - animate_emoji: true, - animate_stickers: 0, - contact_sync_enabled: false, - convert_emoticons: false, - custom_status: null, - default_guilds_restricted: false, - detect_platform_accounts: false, - developer_mode: true, - disable_games_tab: true, - enable_tts_command: false, - explicit_content_filter: 0, - friend_source_flags: { all: true }, - gateway_connected: false, - gif_auto_play: true, - guild_folders: [], - guild_positions: [], - inline_attachment_media: true, - inline_embed_media: true, - locale: "en-US", - message_display_compact: true, - native_phone_integration_enabled: true, - render_embeds: true, - render_reactions: true, - restricted_guilds: [], - show_current_game: true, - status: "online", - stream_notifications_enabled: false, - theme: "dark", - timezone_offset: 0, // TODO: timezone from request -}; - -export interface UserSettings { - afk_timeout: number; - allow_accessibility_detection: boolean; - animate_emoji: boolean; - animate_stickers: number; - contact_sync_enabled: boolean; - convert_emoticons: boolean; - custom_status: { - emoji_id?: string; - emoji_name?: string; - expires_at?: number; - text?: string; - } | null; - default_guilds_restricted: boolean; - detect_platform_accounts: boolean; - developer_mode: boolean; - disable_games_tab: boolean; - enable_tts_command: boolean; - explicit_content_filter: number; - friend_source_flags: { all: boolean }; - gateway_connected: boolean; - gif_auto_play: boolean; - // every top guild is displayed as a "folder" - guild_folders: { - color: number; - guild_ids: string[]; - id: number; - name: string; - }[]; - guild_positions: string[]; // guild ids ordered by position - inline_attachment_media: boolean; - inline_embed_media: boolean; - locale: string; // en_US - message_display_compact: boolean; - native_phone_integration_enabled: boolean; - render_embeds: boolean; - render_reactions: boolean; - restricted_guilds: string[]; - show_current_game: boolean; - status: "online" | "offline" | "dnd" | "idle" | "invisible"; - stream_notifications_enabled: boolean; - theme: "dark" | "white"; // dark - timezone_offset: number; // e.g -60 -} - export const CUSTOM_USER_FLAG_OFFSET = BigInt(1) << BigInt(32); export class UserFlags extends BitField { @@ -398,6 +316,6 @@ export class UserFlags extends BitField { VERIFIED_BOT: BigInt(1) << BigInt(16), EARLY_VERIFIED_BOT_DEVELOPER: BigInt(1) << BigInt(17), CERTIFIED_MODERATOR: BigInt(1) << BigInt(18), - BOT_HTTP_INTERACTIONS: BigInt(1) << BigInt(19), + BOT_HTTP_INTERACTIONS: BigInt(1) << BigInt(19) }; } diff --git a/util/src/entities/UserGroup.ts b/src/util/entities/UserGroup.ts
index 709b9d0b..08d68a4e 100644 --- a/util/src/entities/UserGroup.ts +++ b/src/util/entities/UserGroup.ts
@@ -1,7 +1,6 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; import { BaseClass } from "./BaseClass"; -import { Guild } from "./Guild"; import { User } from "./User"; @Entity("groups") @@ -11,11 +10,11 @@ export class UserGroup extends BaseClass { @Column() hoist: boolean; - + @JoinColumn({ name: "controller", referencedColumnName: "id" }) @ManyToOne(() => User) controller?: User; - + @Column() mentionable_by?: string; @@ -27,11 +26,10 @@ export class UserGroup extends BaseClass { @Column({ nullable: true }) icon: string; - + @Column({ nullable: true }) parent?: string; - - @Column({ type: "simple-array", nullable: true}) - associciations: string[]; + @Column({ type: "simple-array", nullable: true }) + associciations: string[]; } diff --git a/src/util/entities/UserSettings.ts b/src/util/entities/UserSettings.ts new file mode 100644
index 00000000..9fa18a4d --- /dev/null +++ b/src/util/entities/UserSettings.ts
@@ -0,0 +1,119 @@ +import { Column, Entity } from "typeorm"; +import { BaseClassWithoutId, PrimaryIdColumn } from "."; + +@Entity("user_settings") +export class UserSettings extends BaseClassWithoutId { + @PrimaryIdColumn() + id: string; + + @Column({ nullable: true }) + afk_timeout: number = 3600; + + @Column({ nullable: true }) + allow_accessibility_detection: boolean = true; + + @Column({ nullable: true }) + animate_emoji: boolean = true; + + @Column({ nullable: true }) + animate_stickers: number = 0; + + @Column({ nullable: true }) + contact_sync_enabled: boolean = false; + + @Column({ nullable: true }) + convert_emoticons: boolean = false; + + @Column({ nullable: true, type: "simple-json" }) + custom_status: CustomStatus | null = null; + + @Column({ nullable: true }) + default_guilds_restricted: boolean = false; + + @Column({ nullable: true }) + detect_platform_accounts: boolean = false; + + @Column({ nullable: true }) + developer_mode: boolean = true; + + @Column({ nullable: true }) + disable_games_tab: boolean = true; + + @Column({ nullable: true }) + enable_tts_command: boolean = false; + + @Column({ nullable: true }) + explicit_content_filter: number = 0; + + @Column({ nullable: true, type: "simple-json" }) + friend_source_flags: FriendSourceFlags = { all: true }; + + @Column({ nullable: true }) + gateway_connected: boolean = false; + + @Column({ nullable: true }) + gif_auto_play: boolean = false; + + @Column({ nullable: true, type: "simple-json" }) + guild_folders: GuildFolder[] = []; // every top guild is displayed as a "folder" + + @Column({ nullable: true, type: "simple-json" }) + guild_positions: string[] = []; // guild ids ordered by position + + @Column({ nullable: true }) + inline_attachment_media: boolean = true; + + @Column({ nullable: true }) + inline_embed_media: boolean = true; + + @Column({ nullable: true }) + locale: string = "en-US"; // en_US + + @Column({ nullable: true }) + message_display_compact: boolean = false; + + @Column({ nullable: true }) + native_phone_integration_enabled: boolean = true; + + @Column({ nullable: true }) + render_embeds: boolean = true; + + @Column({ nullable: true }) + render_reactions: boolean = true; + + @Column({ nullable: true, type: "simple-json" }) + restricted_guilds: string[] = []; + + @Column({ nullable: true }) + show_current_game: boolean = true; + + @Column({ nullable: true }) + status: "online" | "offline" | "dnd" | "idle" | "invisible" = "online"; + + @Column({ nullable: true }) + stream_notifications_enabled: boolean = false; + + @Column({ nullable: true }) + theme: "dark" | "white" = "dark"; // dark + + @Column({ nullable: true }) + timezone_offset: number = 0; // e.g -60 +} + +interface CustomStatus { + emoji_id?: string; + emoji_name?: string; + expires_at?: number; + text?: string; +} + +interface GuildFolder { + color: number; + guild_ids: string[]; + id: number; + name: string; +} + +interface FriendSourceFlags { + all: boolean; +} diff --git a/util/src/entities/VoiceState.ts b/src/util/entities/VoiceState.ts
index 75748a01..baf2c687 100644 --- a/util/src/entities/VoiceState.ts +++ b/src/util/entities/VoiceState.ts
@@ -2,8 +2,8 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; -import { User } from "./User"; import { Member } from "./Member"; +import { User } from "./User"; //https://gist.github.com/vassjozsef/e482c65df6ee1facaace8b3c9ff66145#file-voice_state-ex @Entity("voice_states") @@ -14,7 +14,7 @@ export class VoiceState extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild?: Guild; @@ -24,7 +24,7 @@ export class VoiceState extends BaseClass { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: Channel; @@ -34,7 +34,7 @@ export class VoiceState extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; diff --git a/util/src/entities/Webhook.ts b/src/util/entities/Webhook.ts
index 89538417..3d94ddb6 100644 --- a/util/src/entities/Webhook.ts +++ b/src/util/entities/Webhook.ts
@@ -7,7 +7,7 @@ import { User } from "./User"; export enum WebhookType { Incoming = 1, - ChannelFollower = 2, + ChannelFollower = 2 } @Entity("webhooks") @@ -30,7 +30,7 @@ export class Webhook extends BaseClass { @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) guild: Guild; @@ -40,7 +40,7 @@ export class Webhook extends BaseClass { @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) channel: Channel; @@ -50,7 +50,7 @@ export class Webhook extends BaseClass { @JoinColumn({ name: "application_id" }) @ManyToOne(() => Application, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) application: Application; @@ -60,7 +60,7 @@ export class Webhook extends BaseClass { @JoinColumn({ name: "user_id" }) @ManyToOne(() => User, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) user: User; @@ -70,7 +70,7 @@ export class Webhook extends BaseClass { @JoinColumn({ name: "source_guild_id" }) @ManyToOne(() => Guild, { - onDelete: "CASCADE", + onDelete: "CASCADE" }) source_guild: Guild; } diff --git a/util/src/entities/index.ts b/src/util/entities/index.ts
index f023d5a6..2b91c2ba 100644 --- a/util/src/entities/index.ts +++ b/src/util/entities/index.ts
@@ -1,10 +1,12 @@ export * from "./Application"; export * from "./Attachment"; export * from "./AuditLog"; +export * from "./BackupCodes"; export * from "./Ban"; export * from "./BaseClass"; export * from "./Categories"; export * from "./Channel"; +export * from "./ClientRelease"; export * from "./Config"; export * from "./ConnectedAccount"; export * from "./Emoji"; @@ -13,6 +15,7 @@ export * from "./Invite"; export * from "./Member"; export * from "./Message"; export * from "./Migration"; +export * from "./Note"; export * from "./RateLimit"; export * from "./ReadState"; export * from "./Recipient"; @@ -25,6 +28,6 @@ export * from "./Team"; export * from "./TeamMember"; export * from "./Template"; export * from "./User"; +export * from "./UserSettings"; export * from "./VoiceState"; export * from "./Webhook"; -export * from "./ClientRelease"; \ No newline at end of file diff --git a/util/src/index.ts b/src/util/index.ts
index ae0f7e54..b26ed278 100644 --- a/util/src/index.ts +++ b/src/util/index.ts
@@ -1,6 +1,9 @@ import "reflect-metadata"; -export * from "./util/index"; -export * from "./interfaces/index"; -export * from "./entities/index"; +export * from "./config/index"; export * from "./dtos/index"; +export * from "./entities/index"; +export * from "./interfaces/index"; +export * from "./schemas"; +export * from "./util/index"; +export * from "./util/MFA"; diff --git a/util/src/interfaces/Activity.ts b/src/util/interfaces/Activity.ts
index 43984afd..3b36b4a6 100644 --- a/util/src/interfaces/Activity.ts +++ b/src/util/interfaces/Activity.ts
@@ -40,5 +40,5 @@ export enum ActivityType { STREAMING = 1, LISTENING = 2, CUSTOM = 4, - COMPETING = 5, + COMPETING = 5 } diff --git a/util/src/interfaces/Event.ts b/src/util/interfaces/Event.ts
index 416082ed..f97f4615 100644 --- a/util/src/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts
@@ -1,19 +1,19 @@ -import { PublicUser, User, UserSettings } from "../entities/User"; +import { Activity, Status } from "."; +import { Sticker, UserSettings } from ".."; +import { ApplicationCommand } from "../entities/Application"; import { Channel } from "../entities/Channel"; -import { Guild } from "../entities/Guild"; -import { Member, PublicMember, UserGuildSettings } from "../entities/Member"; +import { ConnectedAccount } from "../entities/ConnectedAccount"; import { Emoji } from "../entities/Emoji"; -import { Role } from "../entities/Role"; +import { Guild } from "../entities/Guild"; import { Invite } from "../entities/Invite"; +import { PublicMember, UserGuildSettings } from "../entities/Member"; import { Message, PartialEmoji } from "../entities/Message"; +import { RelationshipType } from "../entities/Relationship"; +import { Role } from "../entities/Role"; +import { PublicUser, User } from "../entities/User"; import { VoiceState } from "../entities/VoiceState"; -import { ApplicationCommand } from "../entities/Application"; import { Interaction } from "./Interaction"; -import { ConnectedAccount } from "../entities/ConnectedAccount"; -import { Relationship, RelationshipType } from "../entities/Relationship"; import { Presence } from "./Presence"; -import { Sticker } from ".."; -import { Activity, Status } from "."; export interface Event { guild_id?: string; @@ -93,7 +93,7 @@ export interface ReadyEventData { }; application?: { id: string; - flags: string; + flags: number; }; merged_members?: PublicMember[][]; // probably all users who the user is in contact with @@ -580,7 +580,7 @@ export enum EVENTEnum { ApplicationCommandCreate = "APPLICATION_COMMAND_CREATE", ApplicationCommandUpdate = "APPLICATION_COMMAND_UPDATE", ApplicationCommandDelete = "APPLICATION_COMMAND_DELETE", - SessionsReplace = "SESSIONS_REPLACE", + SessionsReplace = "SESSIONS_REPLACE" } export type EVENT = diff --git a/util/src/interfaces/Interaction.ts b/src/util/interfaces/Interaction.ts
index 5d3aae24..c53a1ed4 100644 --- a/util/src/interfaces/Interaction.ts +++ b/src/util/interfaces/Interaction.ts
@@ -14,7 +14,7 @@ export interface Interaction { export enum InteractionType { SelfCommand = 0, Ping = 1, - ApplicationCommand = 2, + ApplicationCommand = 2 } export enum InteractionResponseType { @@ -23,7 +23,7 @@ export enum InteractionResponseType { Acknowledge = 2, ChannelMessage = 3, ChannelMessageWithSource = 4, - AcknowledgeWithSource = 5, + AcknowledgeWithSource = 5 } export interface InteractionApplicationCommandCallbackData { diff --git a/util/src/interfaces/Presence.ts b/src/util/interfaces/Presence.ts
index 7663891a..5b66139e 100644 --- a/util/src/interfaces/Presence.ts +++ b/src/util/interfaces/Presence.ts
@@ -1,6 +1,6 @@ -import { ClientStatus, Status } from "./Status"; -import { Activity } from "./Activity"; import { PublicUser } from "../entities/User"; +import { Activity } from "./Activity"; +import { ClientStatus, Status } from "./Status"; export interface Presence { user: PublicUser; diff --git a/util/src/interfaces/Status.ts b/src/util/interfaces/Status.ts
index 5d2e1bba..5d2e1bba 100644 --- a/util/src/interfaces/Status.ts +++ b/src/util/interfaces/Status.ts
diff --git a/util/src/interfaces/index.ts b/src/util/interfaces/index.ts
index ab7fa429..a074030e 100644 --- a/util/src/interfaces/index.ts +++ b/src/util/interfaces/index.ts
@@ -1,5 +1,5 @@ export * from "./Activity"; -export * from "./Presence"; -export * from "./Interaction"; export * from "./Event"; +export * from "./Interaction"; +export * from "./Presence"; export * from "./Status"; diff --git a/src/util/migrations/mariadb/1659901151025-initial.ts b/src/util/migrations/mariadb/1659901151025-initial.ts new file mode 100644
index 00000000..1e1f64db --- /dev/null +++ b/src/util/migrations/mariadb/1659901151025-initial.ts
@@ -0,0 +1,1218 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class initial1659901151025 implements MigrationInterface { + name = "initial1659901151025"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE \`config\` ( + \`key\` varchar(255) NOT NULL, + \`value\` text NULL, + PRIMARY KEY (\`key\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`relationships\` ( + \`id\` varchar(255) NOT NULL, + \`from_id\` varchar(255) NOT NULL, + \`to_id\` varchar(255) NOT NULL, + \`nickname\` varchar(255) NULL, + \`type\` int NOT NULL, + UNIQUE INDEX \`IDX_a0b2ff0a598df0b0d055934a17\` (\`from_id\`, \`to_id\`), + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`connected_accounts\` ( + \`id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NULL, + \`access_token\` varchar(255) NOT NULL, + \`friend_sync\` tinyint NOT NULL, + \`name\` varchar(255) NOT NULL, + \`revoked\` tinyint NOT NULL, + \`show_activity\` tinyint NOT NULL, + \`type\` varchar(255) NOT NULL, + \`verified\` tinyint NOT NULL, + \`visibility\` int NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`users\` ( + \`id\` varchar(255) NOT NULL, + \`username\` varchar(255) NOT NULL, + \`discriminator\` varchar(255) NOT NULL, + \`avatar\` varchar(255) NULL, + \`accent_color\` int NULL, + \`banner\` varchar(255) NULL, + \`phone\` varchar(255) NULL, + \`desktop\` tinyint NOT NULL, + \`mobile\` tinyint NOT NULL, + \`premium\` tinyint NOT NULL, + \`premium_type\` int NOT NULL, + \`bot\` tinyint NOT NULL, + \`bio\` varchar(255) NOT NULL, + \`system\` tinyint NOT NULL, + \`nsfw_allowed\` tinyint NOT NULL, + \`mfa_enabled\` tinyint NOT NULL, + \`totp_secret\` varchar(255) NULL, + \`totp_last_ticket\` varchar(255) NULL, + \`created_at\` datetime NOT NULL, + \`premium_since\` datetime NULL, + \`verified\` tinyint NOT NULL, + \`disabled\` tinyint NOT NULL, + \`deleted\` tinyint NOT NULL, + \`email\` varchar(255) NULL, + \`flags\` varchar(255) NOT NULL, + \`public_flags\` int NOT NULL, + \`rights\` bigint NOT NULL, + \`data\` text NOT NULL, + \`fingerprints\` text NOT NULL, + \`settings\` text NOT NULL, + \`extended_settings\` text NOT NULL, + \`notes\` text NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`backup_codes\` ( + \`id\` varchar(255) NOT NULL, + \`code\` varchar(255) NOT NULL, + \`consumed\` tinyint NOT NULL, + \`expired\` tinyint NOT NULL, + \`user_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`bans\` ( + \`id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + \`executor_id\` varchar(255) NULL, + \`ip\` varchar(255) NOT NULL, + \`reason\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`recipients\` ( + \`id\` varchar(255) NOT NULL, + \`channel_id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NOT NULL, + \`closed\` tinyint NOT NULL DEFAULT 0, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`roles\` ( + \`id\` varchar(255) NOT NULL, + \`guild_id\` varchar(255) NULL, + \`color\` int NOT NULL, + \`hoist\` tinyint NOT NULL, + \`managed\` tinyint NOT NULL, + \`mentionable\` tinyint NOT NULL, + \`name\` varchar(255) NOT NULL, + \`permissions\` varchar(255) NOT NULL, + \`position\` int NOT NULL, + \`icon\` varchar(255) NULL, + \`unicode_emoji\` varchar(255) NULL, + \`tags\` text NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`members\` ( + \`index\` int NOT NULL AUTO_INCREMENT, + \`id\` varchar(255) NOT NULL, + \`guild_id\` varchar(255) NOT NULL, + \`nick\` varchar(255) NULL, + \`joined_at\` datetime NOT NULL, + \`premium_since\` bigint NULL, + \`deaf\` tinyint NOT NULL, + \`mute\` tinyint NOT NULL, + \`pending\` tinyint NOT NULL, + \`settings\` text NOT NULL, + \`last_message_id\` varchar(255) NULL, + \`joined_by\` varchar(255) NULL, + UNIQUE INDEX \`IDX_bb2bf9386ac443afbbbf9f12d3\` (\`id\`, \`guild_id\`), + PRIMARY KEY (\`index\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`webhooks\` ( + \`id\` varchar(255) NOT NULL, + \`type\` int NOT NULL, + \`name\` varchar(255) NULL, + \`avatar\` varchar(255) NULL, + \`token\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + \`channel_id\` varchar(255) NULL, + \`application_id\` varchar(255) NULL, + \`user_id\` varchar(255) NULL, + \`source_guild_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`stickers\` ( + \`id\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`description\` varchar(255) NULL, + \`available\` tinyint NULL, + \`tags\` varchar(255) NULL, + \`pack_id\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + \`user_id\` varchar(255) NULL, + \`type\` int NOT NULL, + \`format_type\` int NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`attachments\` ( + \`id\` varchar(255) NOT NULL, + \`filename\` varchar(255) NOT NULL, + \`size\` int NOT NULL, + \`url\` varchar(255) NOT NULL, + \`proxy_url\` varchar(255) NOT NULL, + \`height\` int NULL, + \`width\` int NULL, + \`content_type\` varchar(255) NULL, + \`message_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`messages\` ( + \`id\` varchar(255) NOT NULL, + \`channel_id\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + \`author_id\` varchar(255) NULL, + \`member_id\` varchar(255) NULL, + \`webhook_id\` varchar(255) NULL, + \`application_id\` varchar(255) NULL, + \`content\` varchar(255) NULL, + \`timestamp\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + \`edited_timestamp\` datetime NULL, + \`tts\` tinyint NULL, + \`mention_everyone\` tinyint NULL, + \`embeds\` text NOT NULL, + \`reactions\` text NOT NULL, + \`nonce\` text NULL, + \`pinned\` tinyint NULL, + \`type\` int NOT NULL, + \`activity\` text NULL, + \`flags\` varchar(255) NULL, + \`message_reference\` text NULL, + \`interaction\` text NULL, + \`components\` text NULL, + \`message_reference_id\` varchar(255) NULL, + INDEX \`IDX_86b9109b155eb70c0a2ca3b4b6\` (\`channel_id\`), + INDEX \`IDX_05535bc695e9f7ee104616459d\` (\`author_id\`), + UNIQUE INDEX \`IDX_3ed7a60fb7dbe04e1ba9332a8b\` (\`channel_id\`, \`id\`), + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`read_states\` ( + \`id\` varchar(255) NOT NULL, + \`channel_id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NOT NULL, + \`last_message_id\` varchar(255) NULL, + \`public_ack\` varchar(255) NULL, + \`notifications_cursor\` varchar(255) NULL, + \`last_pin_timestamp\` datetime NULL, + \`mention_count\` int NULL, + UNIQUE INDEX \`IDX_0abf8b443321bd3cf7f81ee17a\` (\`channel_id\`, \`user_id\`), + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`invites\` ( + \`code\` varchar(255) NOT NULL, + \`temporary\` tinyint NOT NULL, + \`uses\` int NOT NULL, + \`max_uses\` int NOT NULL, + \`max_age\` int NOT NULL, + \`created_at\` datetime NOT NULL, + \`expires_at\` datetime NOT NULL, + \`guild_id\` varchar(255) NULL, + \`channel_id\` varchar(255) NULL, + \`inviter_id\` varchar(255) NULL, + \`target_user_id\` varchar(255) NULL, + \`target_user_type\` int NULL, + \`vanity_url\` tinyint NULL, + PRIMARY KEY (\`code\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`voice_states\` ( + \`id\` varchar(255) NOT NULL, + \`guild_id\` varchar(255) NULL, + \`channel_id\` varchar(255) NULL, + \`user_id\` varchar(255) NULL, + \`session_id\` varchar(255) NOT NULL, + \`token\` varchar(255) NULL, + \`deaf\` tinyint NOT NULL, + \`mute\` tinyint NOT NULL, + \`self_deaf\` tinyint NOT NULL, + \`self_mute\` tinyint NOT NULL, + \`self_stream\` tinyint NULL, + \`self_video\` tinyint NOT NULL, + \`suppress\` tinyint NOT NULL, + \`request_to_speak_timestamp\` datetime NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`channels\` ( + \`id\` varchar(255) NOT NULL, + \`created_at\` datetime NOT NULL, + \`name\` varchar(255) NULL, + \`icon\` text NULL, + \`type\` int NOT NULL, + \`last_message_id\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + \`parent_id\` varchar(255) NULL, + \`owner_id\` varchar(255) NULL, + \`last_pin_timestamp\` int NULL, + \`default_auto_archive_duration\` int NULL, + \`position\` int NULL, + \`permission_overwrites\` text NULL, + \`video_quality_mode\` int NULL, + \`bitrate\` int NULL, + \`user_limit\` int NULL, + \`nsfw\` tinyint NULL, + \`rate_limit_per_user\` int NULL, + \`topic\` varchar(255) NULL, + \`retention_policy_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`emojis\` ( + \`id\` varchar(255) NOT NULL, + \`animated\` tinyint NOT NULL, + \`available\` tinyint NOT NULL, + \`guild_id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NULL, + \`managed\` tinyint NOT NULL, + \`name\` varchar(255) NOT NULL, + \`require_colons\` tinyint NOT NULL, + \`roles\` text NOT NULL, + \`groups\` text NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`templates\` ( + \`id\` varchar(255) NOT NULL, + \`code\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`description\` varchar(255) NULL, + \`usage_count\` int NULL, + \`creator_id\` varchar(255) NULL, + \`created_at\` datetime NOT NULL, + \`updated_at\` datetime NOT NULL, + \`source_guild_id\` varchar(255) NULL, + \`serialized_source_guild\` text NOT NULL, + UNIQUE INDEX \`IDX_be38737bf339baf63b1daeffb5\` (\`code\`), + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`guilds\` ( + \`id\` varchar(255) NOT NULL, + \`afk_channel_id\` varchar(255) NULL, + \`afk_timeout\` int NULL, + \`banner\` varchar(255) NULL, + \`default_message_notifications\` int NULL, + \`description\` varchar(255) NULL, + \`discovery_splash\` varchar(255) NULL, + \`explicit_content_filter\` int NULL, + \`features\` text NOT NULL, + \`primary_category_id\` int NULL, + \`icon\` varchar(255) NULL, + \`large\` tinyint NULL, + \`max_members\` int NULL, + \`max_presences\` int NULL, + \`max_video_channel_users\` int NULL, + \`member_count\` int NULL, + \`presence_count\` int NULL, + \`template_id\` varchar(255) NULL, + \`mfa_level\` int NULL, + \`name\` varchar(255) NOT NULL, + \`owner_id\` varchar(255) NULL, + \`preferred_locale\` varchar(255) NULL, + \`premium_subscription_count\` int NULL, + \`premium_tier\` int NULL, + \`public_updates_channel_id\` varchar(255) NULL, + \`rules_channel_id\` varchar(255) NULL, + \`region\` varchar(255) NULL, + \`splash\` varchar(255) NULL, + \`system_channel_id\` varchar(255) NULL, + \`system_channel_flags\` int NULL, + \`unavailable\` tinyint NULL, + \`verification_level\` int NULL, + \`welcome_screen\` text NOT NULL, + \`widget_channel_id\` varchar(255) NULL, + \`widget_enabled\` tinyint NULL, + \`nsfw_level\` int NULL, + \`nsfw\` tinyint NULL, + \`parent\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`team_members\` ( + \`id\` varchar(255) NOT NULL, + \`membership_state\` int NOT NULL, + \`permissions\` text NOT NULL, + \`team_id\` varchar(255) NULL, + \`user_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`teams\` ( + \`id\` varchar(255) NOT NULL, + \`icon\` varchar(255) NULL, + \`name\` varchar(255) NOT NULL, + \`owner_user_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`applications\` ( + \`id\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`icon\` varchar(255) NULL, + \`description\` varchar(255) NOT NULL, + \`rpc_origins\` text NULL, + \`bot_public\` tinyint NOT NULL, + \`bot_require_code_grant\` tinyint NOT NULL, + \`terms_of_service_url\` varchar(255) NULL, + \`privacy_policy_url\` varchar(255) NULL, + \`summary\` varchar(255) NULL, + \`verify_key\` varchar(255) NOT NULL, + \`primary_sku_id\` varchar(255) NULL, + \`slug\` varchar(255) NULL, + \`cover_image\` varchar(255) NULL, + \`flags\` varchar(255) NOT NULL, + \`owner_id\` varchar(255) NULL, + \`team_id\` varchar(255) NULL, + \`guild_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`audit_logs\` ( + \`id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NULL, + \`action_type\` int NOT NULL, + \`options\` text NULL, + \`changes\` text NOT NULL, + \`reason\` varchar(255) NULL, + \`target_id\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`categories\` ( + \`id\` int NOT NULL, + \`name\` varchar(255) NULL, + \`localizations\` text NOT NULL, + \`is_primary\` tinyint NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`rate_limits\` ( + \`id\` varchar(255) NOT NULL, + \`executor_id\` varchar(255) NOT NULL, + \`hits\` int NOT NULL, + \`blocked\` tinyint NOT NULL, + \`expires_at\` datetime NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`sessions\` ( + \`id\` varchar(255) NOT NULL, + \`user_id\` varchar(255) NULL, + \`session_id\` varchar(255) NOT NULL, + \`activities\` text NULL, + \`client_info\` text NOT NULL, + \`status\` varchar(255) NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`sticker_packs\` ( + \`id\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`description\` varchar(255) NULL, + \`banner_asset_id\` varchar(255) NULL, + \`cover_sticker_id\` varchar(255) NULL, + \`coverStickerId\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`client_release\` ( + \`id\` varchar(255) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`pub_date\` varchar(255) NOT NULL, + \`url\` varchar(255) NOT NULL, + \`deb_url\` varchar(255) NOT NULL, + \`osx_url\` varchar(255) NOT NULL, + \`win_url\` varchar(255) NOT NULL, + \`notes\` varchar(255) NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`notes\` ( + \`id\` varchar(255) NOT NULL, + \`content\` varchar(255) NOT NULL, + \`owner_id\` varchar(255) NULL, + \`target_id\` varchar(255) NULL, + UNIQUE INDEX \`IDX_74e6689b9568cc965b8bfc9150\` (\`owner_id\`, \`target_id\`), + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`member_roles\` ( + \`index\` int NOT NULL, + \`role_id\` varchar(255) NOT NULL, + INDEX \`IDX_5d7ddc8a5f9c167f548625e772\` (\`index\`), + INDEX \`IDX_e9080e7a7997a0170026d5139c\` (\`role_id\`), + PRIMARY KEY (\`index\`, \`role_id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`message_user_mentions\` ( + \`messagesId\` varchar(255) NOT NULL, + \`usersId\` varchar(255) NOT NULL, + INDEX \`IDX_a343387fc560ef378760681c23\` (\`messagesId\`), + INDEX \`IDX_b831eb18ceebd28976239b1e2f\` (\`usersId\`), + PRIMARY KEY (\`messagesId\`, \`usersId\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`message_role_mentions\` ( + \`messagesId\` varchar(255) NOT NULL, + \`rolesId\` varchar(255) NOT NULL, + INDEX \`IDX_a8242cf535337a490b0feaea0b\` (\`messagesId\`), + INDEX \`IDX_29d63eb1a458200851bc37d074\` (\`rolesId\`), + PRIMARY KEY (\`messagesId\`, \`rolesId\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`message_channel_mentions\` ( + \`messagesId\` varchar(255) NOT NULL, + \`channelsId\` varchar(255) NOT NULL, + INDEX \`IDX_2a27102ecd1d81b4582a436092\` (\`messagesId\`), + INDEX \`IDX_bdb8c09e1464cabf62105bf4b9\` (\`channelsId\`), + PRIMARY KEY (\`messagesId\`, \`channelsId\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`message_stickers\` ( + \`messagesId\` varchar(255) NOT NULL, + \`stickersId\` varchar(255) NOT NULL, + INDEX \`IDX_40bb6f23e7cc133292e92829d2\` (\`messagesId\`), + INDEX \`IDX_e22a70819d07659c7a71c112a1\` (\`stickersId\`), + PRIMARY KEY (\`messagesId\`, \`stickersId\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + ALTER TABLE \`relationships\` + ADD CONSTRAINT \`FK_9af4194bab1250b1c584ae4f1d7\` FOREIGN KEY (\`from_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`relationships\` + ADD CONSTRAINT \`FK_9c7f6b98a9843b76dce1b0c878b\` FOREIGN KEY (\`to_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`connected_accounts\` + ADD CONSTRAINT \`FK_f47244225a6a1eac04a3463dd90\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`backup_codes\` + ADD CONSTRAINT \`FK_70066ea80d2f4b871beda32633b\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`bans\` + ADD CONSTRAINT \`FK_5999e8e449f80a236ff72023559\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`bans\` + ADD CONSTRAINT \`FK_9d3ab7dd180ebdd245cdb66ecad\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`bans\` + ADD CONSTRAINT \`FK_07ad88c86d1f290d46748410d58\` FOREIGN KEY (\`executor_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`recipients\` + ADD CONSTRAINT \`FK_2f18ee1ba667f233ae86c0ea60e\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`recipients\` + ADD CONSTRAINT \`FK_6157e8b6ba4e6e3089616481fe2\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`roles\` + ADD CONSTRAINT \`FK_c32c1ab1c4dc7dcb0278c4b1b8b\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`members\` + ADD CONSTRAINT \`FK_28b53062261b996d9c99fa12404\` FOREIGN KEY (\`id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`members\` + ADD CONSTRAINT \`FK_16aceddd5b89825b8ed6029ad1c\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` + ADD CONSTRAINT \`FK_487a7af59d189f744fe394368fc\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` + ADD CONSTRAINT \`FK_df528cf77e82f8032230e7e37d8\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` + ADD CONSTRAINT \`FK_c3e5305461931763b56aa905f1c\` FOREIGN KEY (\`application_id\`) REFERENCES \`applications\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` + ADD CONSTRAINT \`FK_0d523f6f997c86e052c49b1455f\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` + ADD CONSTRAINT \`FK_3a285f4f49c40e0706d3018bc9f\` FOREIGN KEY (\`source_guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` + ADD CONSTRAINT \`FK_e7cfa5cefa6661b3fb8fda8ce69\` FOREIGN KEY (\`pack_id\`) REFERENCES \`sticker_packs\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` + ADD CONSTRAINT \`FK_193d551d852aca5347ef5c9f205\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` + ADD CONSTRAINT \`FK_8f4ee73f2bb2325ff980502e158\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`attachments\` + ADD CONSTRAINT \`FK_623e10eec51ada466c5038979e3\` FOREIGN KEY (\`message_id\`) REFERENCES \`messages\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_86b9109b155eb70c0a2ca3b4b6d\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_b193588441b085352a4c0109423\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_05535bc695e9f7ee104616459d3\` FOREIGN KEY (\`author_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_b0525304f2262b7014245351c76\` FOREIGN KEY (\`member_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_f83c04bcf1df4e5c0e7a52ed348\` FOREIGN KEY (\`webhook_id\`) REFERENCES \`webhooks\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_5d3ec1cb962de6488637fd779d6\` FOREIGN KEY (\`application_id\`) REFERENCES \`applications\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`messages\` + ADD CONSTRAINT \`FK_61a92bb65b302a76d9c1fcd3174\` FOREIGN KEY (\`message_reference_id\`) REFERENCES \`messages\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`read_states\` + ADD CONSTRAINT \`FK_40da2fca4e0eaf7a23b5bfc5d34\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`read_states\` + ADD CONSTRAINT \`FK_195f92e4dd1254a4e348c043763\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_3f4939aa1461e8af57fea3fb05d\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_6a15b051fe5050aa00a4b9ff0f6\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_11a0d394f8fc649c19ce5f16b59\` FOREIGN KEY (\`target_user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` + ADD CONSTRAINT \`FK_03779ef216d4b0358470d9cb748\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` + ADD CONSTRAINT \`FK_9f8d389866b40b6657edd026dd4\` FOREIGN KEY (\`channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` + ADD CONSTRAINT \`FK_5fe1d5f931a67e85039c640001b\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD CONSTRAINT \`FK_c253dafe5f3a03ec00cd8fb4581\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD CONSTRAINT \`FK_3274522d14af40540b1a883fc80\` FOREIGN KEY (\`parent_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD CONSTRAINT \`FK_3873ed438575cce703ecff4fc7b\` FOREIGN KEY (\`owner_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`emojis\` + ADD CONSTRAINT \`FK_4b988e0db89d94cebcf07f598cc\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`emojis\` + ADD CONSTRAINT \`FK_fa7ddd5f9a214e28ce596548421\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`templates\` + ADD CONSTRAINT \`FK_d7374b7f8f5fbfdececa4fb62e1\` FOREIGN KEY (\`creator_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`templates\` + ADD CONSTRAINT \`FK_445d00eaaea0e60a017a5ed0c11\` FOREIGN KEY (\`source_guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_f591a66b8019d87b0fe6c12dad6\` FOREIGN KEY (\`afk_channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_e2a2f873a64a5cf62526de42325\` FOREIGN KEY (\`template_id\`) REFERENCES \`templates\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_fc1a451727e3643ca572a3bb394\` FOREIGN KEY (\`owner_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_8d450b016dc8bec35f36729e4b0\` FOREIGN KEY (\`public_updates_channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_95828668aa333460582e0ca6396\` FOREIGN KEY (\`rules_channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_cfc3d3ad260f8121c95b31a1fce\` FOREIGN KEY (\`system_channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD CONSTRAINT \`FK_9d1d665379eefde7876a17afa99\` FOREIGN KEY (\`widget_channel_id\`) REFERENCES \`channels\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`team_members\` + ADD CONSTRAINT \`FK_fdad7d5768277e60c40e01cdcea\` FOREIGN KEY (\`team_id\`) REFERENCES \`teams\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`team_members\` + ADD CONSTRAINT \`FK_c2bf4967c8c2a6b845dadfbf3d4\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`teams\` + ADD CONSTRAINT \`FK_13f00abf7cb6096c43ecaf8c108\` FOREIGN KEY (\`owner_user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_e57508958bf92b9d9d25231b5e8\` FOREIGN KEY (\`owner_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_a36ed02953077f408d0f3ebc424\` FOREIGN KEY (\`team_id\`) REFERENCES \`teams\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_e5bf78cdbbe9ba91062d74c5aba\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`audit_logs\` + ADD CONSTRAINT \`FK_3cd01cd3ae7aab010310d96ac8e\` FOREIGN KEY (\`target_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`audit_logs\` + ADD CONSTRAINT \`FK_bd2726fd31b35443f2245b93ba0\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`sessions\` + ADD CONSTRAINT \`FK_085d540d9f418cfbdc7bd55bb19\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`sticker_packs\` + ADD CONSTRAINT \`FK_448fafba4355ee1c837bbc865f1\` FOREIGN KEY (\`coverStickerId\`) REFERENCES \`stickers\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`notes\` + ADD CONSTRAINT \`FK_f9e103f8ae67cb1787063597925\` FOREIGN KEY (\`owner_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`notes\` + ADD CONSTRAINT \`FK_23e08e5b4481711d573e1abecdc\` FOREIGN KEY (\`target_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`member_roles\` + ADD CONSTRAINT \`FK_5d7ddc8a5f9c167f548625e772e\` FOREIGN KEY (\`index\`) REFERENCES \`members\`(\`index\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`member_roles\` + ADD CONSTRAINT \`FK_e9080e7a7997a0170026d5139c1\` FOREIGN KEY (\`role_id\`) REFERENCES \`roles\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_user_mentions\` + ADD CONSTRAINT \`FK_a343387fc560ef378760681c236\` FOREIGN KEY (\`messagesId\`) REFERENCES \`messages\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_user_mentions\` + ADD CONSTRAINT \`FK_b831eb18ceebd28976239b1e2f8\` FOREIGN KEY (\`usersId\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_role_mentions\` + ADD CONSTRAINT \`FK_a8242cf535337a490b0feaea0b4\` FOREIGN KEY (\`messagesId\`) REFERENCES \`messages\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_role_mentions\` + ADD CONSTRAINT \`FK_29d63eb1a458200851bc37d074b\` FOREIGN KEY (\`rolesId\`) REFERENCES \`roles\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_channel_mentions\` + ADD CONSTRAINT \`FK_2a27102ecd1d81b4582a4360921\` FOREIGN KEY (\`messagesId\`) REFERENCES \`messages\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_channel_mentions\` + ADD CONSTRAINT \`FK_bdb8c09e1464cabf62105bf4b9d\` FOREIGN KEY (\`channelsId\`) REFERENCES \`channels\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_stickers\` + ADD CONSTRAINT \`FK_40bb6f23e7cc133292e92829d28\` FOREIGN KEY (\`messagesId\`) REFERENCES \`messages\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE \`message_stickers\` + ADD CONSTRAINT \`FK_e22a70819d07659c7a71c112a1f\` FOREIGN KEY (\`stickersId\`) REFERENCES \`stickers\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + CREATE TABLE \`query-result-cache\` ( + \`id\` int NOT NULL AUTO_INCREMENT, + \`identifier\` varchar(255) NULL, + \`time\` bigint NOT NULL, + \`duration\` int NOT NULL, + \`query\` text NOT NULL, + \`result\` text NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP TABLE \`query-result-cache\` + `); + await queryRunner.query(` + ALTER TABLE \`message_stickers\` DROP FOREIGN KEY \`FK_e22a70819d07659c7a71c112a1f\` + `); + await queryRunner.query(` + ALTER TABLE \`message_stickers\` DROP FOREIGN KEY \`FK_40bb6f23e7cc133292e92829d28\` + `); + await queryRunner.query(` + ALTER TABLE \`message_channel_mentions\` DROP FOREIGN KEY \`FK_bdb8c09e1464cabf62105bf4b9d\` + `); + await queryRunner.query(` + ALTER TABLE \`message_channel_mentions\` DROP FOREIGN KEY \`FK_2a27102ecd1d81b4582a4360921\` + `); + await queryRunner.query(` + ALTER TABLE \`message_role_mentions\` DROP FOREIGN KEY \`FK_29d63eb1a458200851bc37d074b\` + `); + await queryRunner.query(` + ALTER TABLE \`message_role_mentions\` DROP FOREIGN KEY \`FK_a8242cf535337a490b0feaea0b4\` + `); + await queryRunner.query(` + ALTER TABLE \`message_user_mentions\` DROP FOREIGN KEY \`FK_b831eb18ceebd28976239b1e2f8\` + `); + await queryRunner.query(` + ALTER TABLE \`message_user_mentions\` DROP FOREIGN KEY \`FK_a343387fc560ef378760681c236\` + `); + await queryRunner.query(` + ALTER TABLE \`member_roles\` DROP FOREIGN KEY \`FK_e9080e7a7997a0170026d5139c1\` + `); + await queryRunner.query(` + ALTER TABLE \`member_roles\` DROP FOREIGN KEY \`FK_5d7ddc8a5f9c167f548625e772e\` + `); + await queryRunner.query(` + ALTER TABLE \`notes\` DROP FOREIGN KEY \`FK_23e08e5b4481711d573e1abecdc\` + `); + await queryRunner.query(` + ALTER TABLE \`notes\` DROP FOREIGN KEY \`FK_f9e103f8ae67cb1787063597925\` + `); + await queryRunner.query(` + ALTER TABLE \`sticker_packs\` DROP FOREIGN KEY \`FK_448fafba4355ee1c837bbc865f1\` + `); + await queryRunner.query(` + ALTER TABLE \`sessions\` DROP FOREIGN KEY \`FK_085d540d9f418cfbdc7bd55bb19\` + `); + await queryRunner.query(` + ALTER TABLE \`audit_logs\` DROP FOREIGN KEY \`FK_bd2726fd31b35443f2245b93ba0\` + `); + await queryRunner.query(` + ALTER TABLE \`audit_logs\` DROP FOREIGN KEY \`FK_3cd01cd3ae7aab010310d96ac8e\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_e5bf78cdbbe9ba91062d74c5aba\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_a36ed02953077f408d0f3ebc424\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_e57508958bf92b9d9d25231b5e8\` + `); + await queryRunner.query(` + ALTER TABLE \`teams\` DROP FOREIGN KEY \`FK_13f00abf7cb6096c43ecaf8c108\` + `); + await queryRunner.query(` + ALTER TABLE \`team_members\` DROP FOREIGN KEY \`FK_c2bf4967c8c2a6b845dadfbf3d4\` + `); + await queryRunner.query(` + ALTER TABLE \`team_members\` DROP FOREIGN KEY \`FK_fdad7d5768277e60c40e01cdcea\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_9d1d665379eefde7876a17afa99\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_cfc3d3ad260f8121c95b31a1fce\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_95828668aa333460582e0ca6396\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_8d450b016dc8bec35f36729e4b0\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_fc1a451727e3643ca572a3bb394\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_e2a2f873a64a5cf62526de42325\` + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP FOREIGN KEY \`FK_f591a66b8019d87b0fe6c12dad6\` + `); + await queryRunner.query(` + ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_445d00eaaea0e60a017a5ed0c11\` + `); + await queryRunner.query(` + ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_d7374b7f8f5fbfdececa4fb62e1\` + `); + await queryRunner.query(` + ALTER TABLE \`emojis\` DROP FOREIGN KEY \`FK_fa7ddd5f9a214e28ce596548421\` + `); + await queryRunner.query(` + ALTER TABLE \`emojis\` DROP FOREIGN KEY \`FK_4b988e0db89d94cebcf07f598cc\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP FOREIGN KEY \`FK_3873ed438575cce703ecff4fc7b\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP FOREIGN KEY \`FK_3274522d14af40540b1a883fc80\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP FOREIGN KEY \`FK_c253dafe5f3a03ec00cd8fb4581\` + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` DROP FOREIGN KEY \`FK_5fe1d5f931a67e85039c640001b\` + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` DROP FOREIGN KEY \`FK_9f8d389866b40b6657edd026dd4\` + `); + await queryRunner.query(` + ALTER TABLE \`voice_states\` DROP FOREIGN KEY \`FK_03779ef216d4b0358470d9cb748\` + `); + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_11a0d394f8fc649c19ce5f16b59\` + `); + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` + `); + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_6a15b051fe5050aa00a4b9ff0f6\` + `); + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_3f4939aa1461e8af57fea3fb05d\` + `); + await queryRunner.query(` + ALTER TABLE \`read_states\` DROP FOREIGN KEY \`FK_195f92e4dd1254a4e348c043763\` + `); + await queryRunner.query(` + ALTER TABLE \`read_states\` DROP FOREIGN KEY \`FK_40da2fca4e0eaf7a23b5bfc5d34\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_61a92bb65b302a76d9c1fcd3174\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_5d3ec1cb962de6488637fd779d6\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_f83c04bcf1df4e5c0e7a52ed348\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_b0525304f2262b7014245351c76\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_05535bc695e9f7ee104616459d3\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_b193588441b085352a4c0109423\` + `); + await queryRunner.query(` + ALTER TABLE \`messages\` DROP FOREIGN KEY \`FK_86b9109b155eb70c0a2ca3b4b6d\` + `); + await queryRunner.query(` + ALTER TABLE \`attachments\` DROP FOREIGN KEY \`FK_623e10eec51ada466c5038979e3\` + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` DROP FOREIGN KEY \`FK_8f4ee73f2bb2325ff980502e158\` + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` DROP FOREIGN KEY \`FK_193d551d852aca5347ef5c9f205\` + `); + await queryRunner.query(` + ALTER TABLE \`stickers\` DROP FOREIGN KEY \`FK_e7cfa5cefa6661b3fb8fda8ce69\` + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` DROP FOREIGN KEY \`FK_3a285f4f49c40e0706d3018bc9f\` + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` DROP FOREIGN KEY \`FK_0d523f6f997c86e052c49b1455f\` + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` DROP FOREIGN KEY \`FK_c3e5305461931763b56aa905f1c\` + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` DROP FOREIGN KEY \`FK_df528cf77e82f8032230e7e37d8\` + `); + await queryRunner.query(` + ALTER TABLE \`webhooks\` DROP FOREIGN KEY \`FK_487a7af59d189f744fe394368fc\` + `); + await queryRunner.query(` + ALTER TABLE \`members\` DROP FOREIGN KEY \`FK_16aceddd5b89825b8ed6029ad1c\` + `); + await queryRunner.query(` + ALTER TABLE \`members\` DROP FOREIGN KEY \`FK_28b53062261b996d9c99fa12404\` + `); + await queryRunner.query(` + ALTER TABLE \`roles\` DROP FOREIGN KEY \`FK_c32c1ab1c4dc7dcb0278c4b1b8b\` + `); + await queryRunner.query(` + ALTER TABLE \`recipients\` DROP FOREIGN KEY \`FK_6157e8b6ba4e6e3089616481fe2\` + `); + await queryRunner.query(` + ALTER TABLE \`recipients\` DROP FOREIGN KEY \`FK_2f18ee1ba667f233ae86c0ea60e\` + `); + await queryRunner.query(` + ALTER TABLE \`bans\` DROP FOREIGN KEY \`FK_07ad88c86d1f290d46748410d58\` + `); + await queryRunner.query(` + ALTER TABLE \`bans\` DROP FOREIGN KEY \`FK_9d3ab7dd180ebdd245cdb66ecad\` + `); + await queryRunner.query(` + ALTER TABLE \`bans\` DROP FOREIGN KEY \`FK_5999e8e449f80a236ff72023559\` + `); + await queryRunner.query(` + ALTER TABLE \`backup_codes\` DROP FOREIGN KEY \`FK_70066ea80d2f4b871beda32633b\` + `); + await queryRunner.query(` + ALTER TABLE \`connected_accounts\` DROP FOREIGN KEY \`FK_f47244225a6a1eac04a3463dd90\` + `); + await queryRunner.query(` + ALTER TABLE \`relationships\` DROP FOREIGN KEY \`FK_9c7f6b98a9843b76dce1b0c878b\` + `); + await queryRunner.query(` + ALTER TABLE \`relationships\` DROP FOREIGN KEY \`FK_9af4194bab1250b1c584ae4f1d7\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_e22a70819d07659c7a71c112a1\` ON \`message_stickers\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_40bb6f23e7cc133292e92829d2\` ON \`message_stickers\` + `); + await queryRunner.query(` + DROP TABLE \`message_stickers\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_bdb8c09e1464cabf62105bf4b9\` ON \`message_channel_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_2a27102ecd1d81b4582a436092\` ON \`message_channel_mentions\` + `); + await queryRunner.query(` + DROP TABLE \`message_channel_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_29d63eb1a458200851bc37d074\` ON \`message_role_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_a8242cf535337a490b0feaea0b\` ON \`message_role_mentions\` + `); + await queryRunner.query(` + DROP TABLE \`message_role_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_b831eb18ceebd28976239b1e2f\` ON \`message_user_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_a343387fc560ef378760681c23\` ON \`message_user_mentions\` + `); + await queryRunner.query(` + DROP TABLE \`message_user_mentions\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_e9080e7a7997a0170026d5139c\` ON \`member_roles\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_5d7ddc8a5f9c167f548625e772\` ON \`member_roles\` + `); + await queryRunner.query(` + DROP TABLE \`member_roles\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_74e6689b9568cc965b8bfc9150\` ON \`notes\` + `); + await queryRunner.query(` + DROP TABLE \`notes\` + `); + await queryRunner.query(` + DROP TABLE \`client_release\` + `); + await queryRunner.query(` + DROP TABLE \`sticker_packs\` + `); + await queryRunner.query(` + DROP TABLE \`sessions\` + `); + await queryRunner.query(` + DROP TABLE \`rate_limits\` + `); + await queryRunner.query(` + DROP TABLE \`categories\` + `); + await queryRunner.query(` + DROP TABLE \`audit_logs\` + `); + await queryRunner.query(` + DROP TABLE \`applications\` + `); + await queryRunner.query(` + DROP TABLE \`teams\` + `); + await queryRunner.query(` + DROP TABLE \`team_members\` + `); + await queryRunner.query(` + DROP TABLE \`guilds\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_be38737bf339baf63b1daeffb5\` ON \`templates\` + `); + await queryRunner.query(` + DROP TABLE \`templates\` + `); + await queryRunner.query(` + DROP TABLE \`emojis\` + `); + await queryRunner.query(` + DROP TABLE \`channels\` + `); + await queryRunner.query(` + DROP TABLE \`voice_states\` + `); + await queryRunner.query(` + DROP TABLE \`invites\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_0abf8b443321bd3cf7f81ee17a\` ON \`read_states\` + `); + await queryRunner.query(` + DROP TABLE \`read_states\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_3ed7a60fb7dbe04e1ba9332a8b\` ON \`messages\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_05535bc695e9f7ee104616459d\` ON \`messages\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_86b9109b155eb70c0a2ca3b4b6\` ON \`messages\` + `); + await queryRunner.query(` + DROP TABLE \`messages\` + `); + await queryRunner.query(` + DROP TABLE \`attachments\` + `); + await queryRunner.query(` + DROP TABLE \`stickers\` + `); + await queryRunner.query(` + DROP TABLE \`webhooks\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_bb2bf9386ac443afbbbf9f12d3\` ON \`members\` + `); + await queryRunner.query(` + DROP TABLE \`members\` + `); + await queryRunner.query(` + DROP TABLE \`roles\` + `); + await queryRunner.query(` + DROP TABLE \`recipients\` + `); + await queryRunner.query(` + DROP TABLE \`bans\` + `); + await queryRunner.query(` + DROP TABLE \`backup_codes\` + `); + await queryRunner.query(` + DROP TABLE \`users\` + `); + await queryRunner.query(` + DROP TABLE \`connected_accounts\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_a0b2ff0a598df0b0d055934a17\` ON \`relationships\` + `); + await queryRunner.query(` + DROP TABLE \`relationships\` + `); + await queryRunner.query(` + DROP TABLE \`config\` + `); + } +} diff --git a/src/util/migrations/mariadb/1659921859145-premium_since_as_date.ts b/src/util/migrations/mariadb/1659921859145-premium_since_as_date.ts new file mode 100644
index 00000000..549d6b9f --- /dev/null +++ b/src/util/migrations/mariadb/1659921859145-premium_since_as_date.ts
@@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class premiumSinceAsDate1659921859145 implements MigrationInterface { + name = "premiumSinceAsDate1659921859145"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`members\` DROP COLUMN \`premium_since\` + `); + await queryRunner.query(` + ALTER TABLE \`members\` + ADD \`premium_since\` datetime NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`members\` DROP COLUMN \`premium_since\` + `); + await queryRunner.query(` + ALTER TABLE \`members\` + ADD \`premium_since\` bigint NULL + `); + } +} diff --git a/src/util/migrations/mariadb/1660130586602-updated-applications.ts b/src/util/migrations/mariadb/1660130586602-updated-applications.ts new file mode 100644
index 00000000..fea076db --- /dev/null +++ b/src/util/migrations/mariadb/1660130586602-updated-applications.ts
@@ -0,0 +1,184 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class updatedApplications1660130586602 implements MigrationInterface { + name = "updatedApplications1660130586602"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_e5bf78cdbbe9ba91062d74c5aba\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`rpc_origins\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`primary_sku_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`slug\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`guild_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`type\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`hook\` tinyint NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`redirect_uris\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`rpc_application_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`store_application_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`verification_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`interactions_endpoint_url\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`integration_public\` tinyint NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`integration_require_code_grant\` tinyint NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`discoverability_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`discovery_eligibility_flags\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`tags\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`install_params\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`bot_user_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD UNIQUE INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` (\`bot_user_id\`) + `); + await queryRunner.query(` + ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`flags\` int NOT NULL + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` (\`bot_user_id\`) + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_2ce5a55796fe4c2f77ece57a647\` FOREIGN KEY (\`bot_user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_2ce5a55796fe4c2f77ece57a647\` + `); + await queryRunner.query(` + DROP INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`flags\` varchar(255) NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`bot_user_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`install_params\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`tags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`discovery_eligibility_flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`discoverability_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`integration_require_code_grant\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`integration_public\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`interactions_endpoint_url\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`verification_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`store_application_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`rpc_application_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`redirect_uris\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`hook\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`type\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`guild_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`slug\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`primary_sku_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`rpc_origins\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_e5bf78cdbbe9ba91062d74c5aba\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } +} diff --git a/src/util/migrations/mariadb/1661273147273-test.ts b/src/util/migrations/mariadb/1661273147273-test.ts new file mode 100644
index 00000000..4e077a11 --- /dev/null +++ b/src/util/migrations/mariadb/1661273147273-test.ts
@@ -0,0 +1,149 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class test1661273147273 implements MigrationInterface { + name = 'test1661273147273' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` + `); + await queryRunner.query(` + CREATE TABLE \`plugin_config\` ( + \`key\` varchar(255) NOT NULL, + \`value\` text NULL, + PRIMARY KEY (\`key\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + CREATE TABLE \`user_settings\` ( + \`id\` varchar(255) NOT NULL, + \`afk_timeout\` int NULL, + \`allow_accessibility_detection\` tinyint NULL, + \`animate_emoji\` tinyint NULL, + \`animate_stickers\` int NULL, + \`contact_sync_enabled\` tinyint NULL, + \`convert_emoticons\` tinyint NULL, + \`custom_status\` text NULL, + \`default_guilds_restricted\` tinyint NULL, + \`detect_platform_accounts\` tinyint NULL, + \`developer_mode\` tinyint NULL, + \`disable_games_tab\` tinyint NULL, + \`enable_tts_command\` tinyint NULL, + \`explicit_content_filter\` int NULL, + \`friend_source_flags\` text NULL, + \`gateway_connected\` tinyint NULL, + \`gif_auto_play\` tinyint NULL, + \`guild_folders\` text NULL, + \`guild_positions\` text NULL, + \`inline_attachment_media\` tinyint NULL, + \`inline_embed_media\` tinyint NULL, + \`locale\` varchar(255) NULL, + \`message_display_compact\` tinyint NULL, + \`native_phone_integration_enabled\` tinyint NULL, + \`render_embeds\` tinyint NULL, + \`render_reactions\` tinyint NULL, + \`restricted_guilds\` text NULL, + \`show_current_game\` tinyint NULL, + \`status\` varchar(255) NULL, + \`stream_notifications_enabled\` tinyint NULL, + \`theme\` varchar(255) NULL, + \`timezone_offset\` int NULL, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + ALTER TABLE \`users\` DROP COLUMN \`settings\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` + ADD \`settingsId\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`users\` + ADD UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` (\`settingsId\`) + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`flags\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`default_thread_rate_limit_per_user\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` + ADD \`premium_progress_bar_enabled\` tinyint NULL + `); + await queryRunner.query(` + ALTER TABLE \`users\` CHANGE \`bio\` \`bio\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`users\` CHANGE \`mfa_enabled\` \`mfa_enabled\` tinyint NULL + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`REL_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) + `); + await queryRunner.query(` + ALTER TABLE \`users\` + ADD CONSTRAINT \`FK_76ba283779c8441fd5ff819c8cf\` FOREIGN KEY (\`settingsId\`) REFERENCES \`user_settings\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` DROP FOREIGN KEY \`FK_76ba283779c8441fd5ff819c8cf\` + `); + await queryRunner.query(` + DROP INDEX \`REL_76ba283779c8441fd5ff819c8c\` ON \`users\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` CHANGE \`mfa_enabled\` \`mfa_enabled\` tinyint NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`users\` CHANGE \`bio\` \`bio\` varchar(255) NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`guilds\` DROP COLUMN \`premium_progress_bar_enabled\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`default_thread_rate_limit_per_user\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` DROP COLUMN \`settingsId\` + `); + await queryRunner.query(` + ALTER TABLE \`users\` + ADD \`settings\` text NOT NULL + `); + await queryRunner.query(` + DROP TABLE \`user_settings\` + `); + await queryRunner.query(` + DROP TABLE \`plugin_config\` + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` (\`bot_user_id\`) + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + +} diff --git a/src/util/migrations/mariadb/1661273179287-test2.ts b/src/util/migrations/mariadb/1661273179287-test2.ts new file mode 100644
index 00000000..0f77f284 --- /dev/null +++ b/src/util/migrations/mariadb/1661273179287-test2.ts
@@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class test21661273179287 implements MigrationInterface { + name = 'test21661273179287' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) + `); + } + +} diff --git a/src/util/migrations/postgres/1659899687168-initial.ts b/src/util/migrations/postgres/1659899687168-initial.ts new file mode 100644
index 00000000..dc89a572 --- /dev/null +++ b/src/util/migrations/postgres/1659899687168-initial.ts
@@ -0,0 +1,1244 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class initial1659899687168 implements MigrationInterface { + name = "initial1659899687168"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "config" ( + "key" character varying NOT NULL, + "value" text, + CONSTRAINT "PK_26489c99ddbb4c91631ef5cc791" PRIMARY KEY ("key") + ) + `); + await queryRunner.query(` + CREATE TABLE "relationships" ( + "id" character varying NOT NULL, + "from_id" character varying NOT NULL, + "to_id" character varying NOT NULL, + "nickname" character varying, + "type" integer NOT NULL, + CONSTRAINT "PK_ba20e2f5cf487408e08e4dcecaf" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_a0b2ff0a598df0b0d055934a17" ON "relationships" ("from_id", "to_id") + `); + await queryRunner.query(` + CREATE TABLE "connected_accounts" ( + "id" character varying NOT NULL, + "user_id" character varying, + "access_token" character varying NOT NULL, + "friend_sync" boolean NOT NULL, + "name" character varying NOT NULL, + "revoked" boolean NOT NULL, + "show_activity" boolean NOT NULL, + "type" character varying NOT NULL, + "verified" boolean NOT NULL, + "visibility" integer NOT NULL, + CONSTRAINT "PK_70416f1da0be645bb31da01c774" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" character varying NOT NULL, + "username" character varying NOT NULL, + "discriminator" character varying NOT NULL, + "avatar" character varying, + "accent_color" integer, + "banner" character varying, + "phone" character varying, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" character varying NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" character varying, + "totp_last_ticket" character varying, + "created_at" TIMESTAMP NOT NULL, + "premium_since" TIMESTAMP, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" character varying, + "flags" character varying NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "settings" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "backup_codes" ( + "id" character varying NOT NULL, + "code" character varying NOT NULL, + "consumed" boolean NOT NULL, + "expired" boolean NOT NULL, + "user_id" character varying, + CONSTRAINT "PK_34ab957382dbc57e8fb53f1638f" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "bans" ( + "id" character varying NOT NULL, + "user_id" character varying, + "guild_id" character varying, + "executor_id" character varying, + "ip" character varying NOT NULL, + "reason" character varying, + CONSTRAINT "PK_a4d6f261bffa4615c62d756566a" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "recipients" ( + "id" character varying NOT NULL, + "channel_id" character varying NOT NULL, + "user_id" character varying NOT NULL, + "closed" boolean NOT NULL DEFAULT false, + CONSTRAINT "PK_de8fc5a9c364568f294798fe1e9" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "roles" ( + "id" character varying NOT NULL, + "guild_id" character varying, + "color" integer NOT NULL, + "hoist" boolean NOT NULL, + "managed" boolean NOT NULL, + "mentionable" boolean NOT NULL, + "name" character varying NOT NULL, + "permissions" character varying NOT NULL, + "position" integer NOT NULL, + "icon" character varying, + "unicode_emoji" character varying, + "tags" text, + CONSTRAINT "PK_c1433d71a4838793a49dcad46ab" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "members" ( + "index" SERIAL NOT NULL, + "id" character varying NOT NULL, + "guild_id" character varying NOT NULL, + "nick" character varying, + "joined_at" TIMESTAMP NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" character varying, + "joined_by" character varying, + CONSTRAINT "PK_b4a6b8c2478e5df990909c6cf6a" PRIMARY KEY ("index") + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + CREATE TABLE "webhooks" ( + "id" character varying NOT NULL, + "type" integer NOT NULL, + "name" character varying, + "avatar" character varying, + "token" character varying, + "guild_id" character varying, + "channel_id" character varying, + "application_id" character varying, + "user_id" character varying, + "source_guild_id" character varying, + CONSTRAINT "PK_9e8795cfc899ab7bdaa831e8527" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "stickers" ( + "id" character varying NOT NULL, + "name" character varying NOT NULL, + "description" character varying, + "available" boolean, + "tags" character varying, + "pack_id" character varying, + "guild_id" character varying, + "user_id" character varying, + "type" integer NOT NULL, + "format_type" integer NOT NULL, + CONSTRAINT "PK_e1dafa4063a5532645cc2810374" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "attachments" ( + "id" character varying NOT NULL, + "filename" character varying NOT NULL, + "size" integer NOT NULL, + "url" character varying NOT NULL, + "proxy_url" character varying NOT NULL, + "height" integer, + "width" integer, + "content_type" character varying, + "message_id" character varying, + CONSTRAINT "PK_5e1f050bcff31e3084a1d662412" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "messages" ( + "id" character varying NOT NULL, + "channel_id" character varying, + "guild_id" character varying, + "author_id" character varying, + "member_id" character varying, + "webhook_id" character varying, + "application_id" character varying, + "content" character varying, + "timestamp" TIMESTAMP NOT NULL DEFAULT now(), + "edited_timestamp" TIMESTAMP, + "tts" boolean, + "mention_everyone" boolean, + "embeds" text NOT NULL, + "reactions" text NOT NULL, + "nonce" text, + "pinned" boolean, + "type" integer NOT NULL, + "activity" text, + "flags" character varying, + "message_reference" text, + "interaction" text, + "components" text, + "message_reference_id" character varying, + CONSTRAINT "PK_18325f38ae6de43878487eff986" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" ON "messages" ("channel_id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_05535bc695e9f7ee104616459d" ON "messages" ("author_id") + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" ON "messages" ("channel_id", "id") + `); + await queryRunner.query(` + CREATE TABLE "read_states" ( + "id" character varying NOT NULL, + "channel_id" character varying NOT NULL, + "user_id" character varying NOT NULL, + "last_message_id" character varying, + "public_ack" character varying, + "notifications_cursor" character varying, + "last_pin_timestamp" TIMESTAMP, + "mention_count" integer, + CONSTRAINT "PK_e6956a804978f01b713b1ed58e2" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_0abf8b443321bd3cf7f81ee17a" ON "read_states" ("channel_id", "user_id") + `); + await queryRunner.query(` + CREATE TABLE "invites" ( + "code" character varying NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" TIMESTAMP NOT NULL, + "expires_at" TIMESTAMP NOT NULL, + "guild_id" character varying, + "channel_id" character varying, + "inviter_id" character varying, + "target_user_id" character varying, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "PK_33fd8a248db1cd832baa8aa25bf" PRIMARY KEY ("code") + ) + `); + await queryRunner.query(` + CREATE TABLE "voice_states" ( + "id" character varying NOT NULL, + "guild_id" character varying, + "channel_id" character varying, + "user_id" character varying, + "session_id" character varying NOT NULL, + "token" character varying, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "self_deaf" boolean NOT NULL, + "self_mute" boolean NOT NULL, + "self_stream" boolean, + "self_video" boolean NOT NULL, + "suppress" boolean NOT NULL, + "request_to_speak_timestamp" TIMESTAMP, + CONSTRAINT "PK_ada09a50c134fad1369b510e3ce" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "channels" ( + "id" character varying NOT NULL, + "created_at" TIMESTAMP NOT NULL, + "name" character varying, + "icon" text, + "type" integer NOT NULL, + "last_message_id" character varying, + "guild_id" character varying, + "parent_id" character varying, + "owner_id" character varying, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" character varying, + "retention_policy_id" character varying, + CONSTRAINT "PK_bc603823f3f741359c2339389f9" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "emojis" ( + "id" character varying NOT NULL, + "animated" boolean NOT NULL, + "available" boolean NOT NULL, + "guild_id" character varying NOT NULL, + "user_id" character varying, + "managed" boolean NOT NULL, + "name" character varying NOT NULL, + "require_colons" boolean NOT NULL, + "roles" text NOT NULL, + "groups" text, + CONSTRAINT "PK_9adb96a675f555c6169bad7ba62" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "templates" ( + "id" character varying NOT NULL, + "code" character varying NOT NULL, + "name" character varying NOT NULL, + "description" character varying, + "usage_count" integer, + "creator_id" character varying, + "created_at" TIMESTAMP NOT NULL, + "updated_at" TIMESTAMP NOT NULL, + "source_guild_id" character varying, + "serialized_source_guild" text NOT NULL, + CONSTRAINT "UQ_be38737bf339baf63b1daeffb55" UNIQUE ("code"), + CONSTRAINT "PK_515948649ce0bbbe391de702ae5" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" character varying NOT NULL, + "afk_channel_id" character varying, + "afk_timeout" integer, + "banner" character varying, + "default_message_notifications" integer, + "description" character varying, + "discovery_splash" character varying, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" character varying, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" character varying, + "mfa_level" integer, + "name" character varying NOT NULL, + "owner_id" character varying, + "preferred_locale" character varying, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" character varying, + "rules_channel_id" character varying, + "region" character varying, + "splash" character varying, + "system_channel_id" character varying, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" character varying, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" character varying, + CONSTRAINT "PK_e7e7f2a51bd6d96a9ac2aa560f9" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "team_members" ( + "id" character varying NOT NULL, + "membership_state" integer NOT NULL, + "permissions" text NOT NULL, + "team_id" character varying, + "user_id" character varying, + CONSTRAINT "PK_ca3eae89dcf20c9fd95bf7460aa" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "teams" ( + "id" character varying NOT NULL, + "icon" character varying, + "name" character varying NOT NULL, + "owner_user_id" character varying, + CONSTRAINT "PK_7e5523774a38b08a6236d322403" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" character varying NOT NULL, + "name" character varying NOT NULL, + "icon" character varying, + "description" character varying NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" character varying, + "privacy_policy_url" character varying, + "summary" character varying, + "verify_key" character varying NOT NULL, + "primary_sku_id" character varying, + "slug" character varying, + "cover_image" character varying, + "flags" character varying NOT NULL, + "owner_id" character varying, + "team_id" character varying, + "guild_id" character varying, + CONSTRAINT "PK_938c0a27255637bde919591888f" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "audit_logs" ( + "id" character varying NOT NULL, + "user_id" character varying, + "action_type" integer NOT NULL, + "options" text, + "changes" text NOT NULL, + "reason" character varying, + "target_id" character varying, + CONSTRAINT "PK_1bb179d048bbc581caa3b013439" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "categories" ( + "id" integer NOT NULL, + "name" character varying, + "localizations" text NOT NULL, + "is_primary" boolean, + CONSTRAINT "PK_24dbc6126a28ff948da33e97d3b" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "rate_limits" ( + "id" character varying NOT NULL, + "executor_id" character varying NOT NULL, + "hits" integer NOT NULL, + "blocked" boolean NOT NULL, + "expires_at" TIMESTAMP NOT NULL, + CONSTRAINT "PK_3b4449f1f5fc167d921ee619f65" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "sessions" ( + "id" character varying NOT NULL, + "user_id" character varying, + "session_id" character varying NOT NULL, + "activities" text, + "client_info" text NOT NULL, + "status" character varying NOT NULL, + CONSTRAINT "PK_3238ef96f18b355b671619111bc" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "sticker_packs" ( + "id" character varying NOT NULL, + "name" character varying NOT NULL, + "description" character varying, + "banner_asset_id" character varying, + "cover_sticker_id" character varying, + "coverStickerId" character varying, + CONSTRAINT "PK_a27381efea0f876f5d3233af655" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "client_release" ( + "id" character varying NOT NULL, + "name" character varying NOT NULL, + "pub_date" character varying NOT NULL, + "url" character varying NOT NULL, + "deb_url" character varying NOT NULL, + "osx_url" character varying NOT NULL, + "win_url" character varying NOT NULL, + "notes" character varying, + CONSTRAINT "PK_4c4ea258342d2d6ba1be0a71a43" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "notes" ( + "id" character varying NOT NULL, + "content" character varying NOT NULL, + "owner_id" character varying, + "target_id" character varying, + CONSTRAINT "UQ_74e6689b9568cc965b8bfc9150b" UNIQUE ("owner_id", "target_id"), + CONSTRAINT "PK_af6206538ea96c4e77e9f400c3d" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "member_roles" ( + "index" integer NOT NULL, + "role_id" character varying NOT NULL, + CONSTRAINT "PK_951c1d72a0fd1da8760b4a1fd66" PRIMARY KEY ("index", "role_id") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_5d7ddc8a5f9c167f548625e772" ON "member_roles" ("index") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e9080e7a7997a0170026d5139c" ON "member_roles" ("role_id") + `); + await queryRunner.query(` + CREATE TABLE "message_user_mentions" ( + "messagesId" character varying NOT NULL, + "usersId" character varying NOT NULL, + CONSTRAINT "PK_9b9b6e245ad47a48dbd7605d4fb" PRIMARY KEY ("messagesId", "usersId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_a343387fc560ef378760681c23" ON "message_user_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_b831eb18ceebd28976239b1e2f" ON "message_user_mentions" ("usersId") + `); + await queryRunner.query(` + CREATE TABLE "message_role_mentions" ( + "messagesId" character varying NOT NULL, + "rolesId" character varying NOT NULL, + CONSTRAINT "PK_74dba92cc300452a6e14b83ed44" PRIMARY KEY ("messagesId", "rolesId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_a8242cf535337a490b0feaea0b" ON "message_role_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_29d63eb1a458200851bc37d074" ON "message_role_mentions" ("rolesId") + `); + await queryRunner.query(` + CREATE TABLE "message_channel_mentions" ( + "messagesId" character varying NOT NULL, + "channelsId" character varying NOT NULL, + CONSTRAINT "PK_85cb45351497cd9d06a79ced65e" PRIMARY KEY ("messagesId", "channelsId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_2a27102ecd1d81b4582a436092" ON "message_channel_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_bdb8c09e1464cabf62105bf4b9" ON "message_channel_mentions" ("channelsId") + `); + await queryRunner.query(` + CREATE TABLE "message_stickers" ( + "messagesId" character varying NOT NULL, + "stickersId" character varying NOT NULL, + CONSTRAINT "PK_ed820c4093d0b8cd1d2bcf66087" PRIMARY KEY ("messagesId", "stickersId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_40bb6f23e7cc133292e92829d2" ON "message_stickers" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e22a70819d07659c7a71c112a1" ON "message_stickers" ("stickersId") + `); + await queryRunner.query(` + ALTER TABLE "relationships" + ADD CONSTRAINT "FK_9af4194bab1250b1c584ae4f1d7" FOREIGN KEY ("from_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "relationships" + ADD CONSTRAINT "FK_9c7f6b98a9843b76dce1b0c878b" FOREIGN KEY ("to_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "connected_accounts" + ADD CONSTRAINT "FK_f47244225a6a1eac04a3463dd90" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "backup_codes" + ADD CONSTRAINT "FK_70066ea80d2f4b871beda32633b" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "bans" + ADD CONSTRAINT "FK_5999e8e449f80a236ff72023559" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "bans" + ADD CONSTRAINT "FK_9d3ab7dd180ebdd245cdb66ecad" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "bans" + ADD CONSTRAINT "FK_07ad88c86d1f290d46748410d58" FOREIGN KEY ("executor_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "recipients" + ADD CONSTRAINT "FK_2f18ee1ba667f233ae86c0ea60e" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "recipients" + ADD CONSTRAINT "FK_6157e8b6ba4e6e3089616481fe2" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "roles" + ADD CONSTRAINT "FK_c32c1ab1c4dc7dcb0278c4b1b8b" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "members" + ADD CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "members" + ADD CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + ADD CONSTRAINT "FK_487a7af59d189f744fe394368fc" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + ADD CONSTRAINT "FK_df528cf77e82f8032230e7e37d8" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + ADD CONSTRAINT "FK_c3e5305461931763b56aa905f1c" FOREIGN KEY ("application_id") REFERENCES "applications"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + ADD CONSTRAINT "FK_0d523f6f997c86e052c49b1455f" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + ADD CONSTRAINT "FK_3a285f4f49c40e0706d3018bc9f" FOREIGN KEY ("source_guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "stickers" + ADD CONSTRAINT "FK_e7cfa5cefa6661b3fb8fda8ce69" FOREIGN KEY ("pack_id") REFERENCES "sticker_packs"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "stickers" + ADD CONSTRAINT "FK_193d551d852aca5347ef5c9f205" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "stickers" + ADD CONSTRAINT "FK_8f4ee73f2bb2325ff980502e158" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "attachments" + ADD CONSTRAINT "FK_623e10eec51ada466c5038979e3" FOREIGN KEY ("message_id") REFERENCES "messages"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_86b9109b155eb70c0a2ca3b4b6d" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_b193588441b085352a4c0109423" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_05535bc695e9f7ee104616459d3" FOREIGN KEY ("author_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_b0525304f2262b7014245351c76" FOREIGN KEY ("member_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_f83c04bcf1df4e5c0e7a52ed348" FOREIGN KEY ("webhook_id") REFERENCES "webhooks"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_5d3ec1cb962de6488637fd779d6" FOREIGN KEY ("application_id") REFERENCES "applications"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "messages" + ADD CONSTRAINT "FK_61a92bb65b302a76d9c1fcd3174" FOREIGN KEY ("message_reference_id") REFERENCES "messages"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "read_states" + ADD CONSTRAINT "FK_40da2fca4e0eaf7a23b5bfc5d34" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "read_states" + ADD CONSTRAINT "FK_195f92e4dd1254a4e348c043763" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "voice_states" + ADD CONSTRAINT "FK_03779ef216d4b0358470d9cb748" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "voice_states" + ADD CONSTRAINT "FK_9f8d389866b40b6657edd026dd4" FOREIGN KEY ("channel_id") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "voice_states" + ADD CONSTRAINT "FK_5fe1d5f931a67e85039c640001b" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "channels" + ADD CONSTRAINT "FK_c253dafe5f3a03ec00cd8fb4581" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "channels" + ADD CONSTRAINT "FK_3274522d14af40540b1a883fc80" FOREIGN KEY ("parent_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "channels" + ADD CONSTRAINT "FK_3873ed438575cce703ecff4fc7b" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "emojis" + ADD CONSTRAINT "FK_4b988e0db89d94cebcf07f598cc" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "emojis" + ADD CONSTRAINT "FK_fa7ddd5f9a214e28ce596548421" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "templates" + ADD CONSTRAINT "FK_d7374b7f8f5fbfdececa4fb62e1" FOREIGN KEY ("creator_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "templates" + ADD CONSTRAINT "FK_445d00eaaea0e60a017a5ed0c11" FOREIGN KEY ("source_guild_id") REFERENCES "guilds"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "team_members" + ADD CONSTRAINT "FK_fdad7d5768277e60c40e01cdcea" FOREIGN KEY ("team_id") REFERENCES "teams"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "team_members" + ADD CONSTRAINT "FK_c2bf4967c8c2a6b845dadfbf3d4" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "teams" + ADD CONSTRAINT "FK_13f00abf7cb6096c43ecaf8c108" FOREIGN KEY ("owner_user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "audit_logs" + ADD CONSTRAINT "FK_3cd01cd3ae7aab010310d96ac8e" FOREIGN KEY ("target_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "audit_logs" + ADD CONSTRAINT "FK_bd2726fd31b35443f2245b93ba0" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "sessions" + ADD CONSTRAINT "FK_085d540d9f418cfbdc7bd55bb19" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "sticker_packs" + ADD CONSTRAINT "FK_448fafba4355ee1c837bbc865f1" FOREIGN KEY ("coverStickerId") REFERENCES "stickers"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "notes" + ADD CONSTRAINT "FK_f9e103f8ae67cb1787063597925" FOREIGN KEY ("owner_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "notes" + ADD CONSTRAINT "FK_23e08e5b4481711d573e1abecdc" FOREIGN KEY ("target_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "member_roles" + ADD CONSTRAINT "FK_5d7ddc8a5f9c167f548625e772e" FOREIGN KEY ("index") REFERENCES "members"("index") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "member_roles" + ADD CONSTRAINT "FK_e9080e7a7997a0170026d5139c1" FOREIGN KEY ("role_id") REFERENCES "roles"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_user_mentions" + ADD CONSTRAINT "FK_a343387fc560ef378760681c236" FOREIGN KEY ("messagesId") REFERENCES "messages"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_user_mentions" + ADD CONSTRAINT "FK_b831eb18ceebd28976239b1e2f8" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_role_mentions" + ADD CONSTRAINT "FK_a8242cf535337a490b0feaea0b4" FOREIGN KEY ("messagesId") REFERENCES "messages"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_role_mentions" + ADD CONSTRAINT "FK_29d63eb1a458200851bc37d074b" FOREIGN KEY ("rolesId") REFERENCES "roles"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_channel_mentions" + ADD CONSTRAINT "FK_2a27102ecd1d81b4582a4360921" FOREIGN KEY ("messagesId") REFERENCES "messages"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_channel_mentions" + ADD CONSTRAINT "FK_bdb8c09e1464cabf62105bf4b9d" FOREIGN KEY ("channelsId") REFERENCES "channels"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_stickers" + ADD CONSTRAINT "FK_40bb6f23e7cc133292e92829d28" FOREIGN KEY ("messagesId") REFERENCES "messages"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + ALTER TABLE "message_stickers" + ADD CONSTRAINT "FK_e22a70819d07659c7a71c112a1f" FOREIGN KEY ("stickersId") REFERENCES "stickers"("id") ON DELETE CASCADE ON UPDATE CASCADE + `); + await queryRunner.query(` + CREATE TABLE "query-result-cache" ( + "id" SERIAL NOT NULL, + "identifier" character varying, + "time" bigint NOT NULL, + "duration" integer NOT NULL, + "query" text NOT NULL, + "result" text NOT NULL, + CONSTRAINT "PK_6a98f758d8bfd010e7e10ffd3d3" PRIMARY KEY ("id") + ) + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP TABLE "query-result-cache" + `); + await queryRunner.query(` + ALTER TABLE "message_stickers" DROP CONSTRAINT "FK_e22a70819d07659c7a71c112a1f" + `); + await queryRunner.query(` + ALTER TABLE "message_stickers" DROP CONSTRAINT "FK_40bb6f23e7cc133292e92829d28" + `); + await queryRunner.query(` + ALTER TABLE "message_channel_mentions" DROP CONSTRAINT "FK_bdb8c09e1464cabf62105bf4b9d" + `); + await queryRunner.query(` + ALTER TABLE "message_channel_mentions" DROP CONSTRAINT "FK_2a27102ecd1d81b4582a4360921" + `); + await queryRunner.query(` + ALTER TABLE "message_role_mentions" DROP CONSTRAINT "FK_29d63eb1a458200851bc37d074b" + `); + await queryRunner.query(` + ALTER TABLE "message_role_mentions" DROP CONSTRAINT "FK_a8242cf535337a490b0feaea0b4" + `); + await queryRunner.query(` + ALTER TABLE "message_user_mentions" DROP CONSTRAINT "FK_b831eb18ceebd28976239b1e2f8" + `); + await queryRunner.query(` + ALTER TABLE "message_user_mentions" DROP CONSTRAINT "FK_a343387fc560ef378760681c236" + `); + await queryRunner.query(` + ALTER TABLE "member_roles" DROP CONSTRAINT "FK_e9080e7a7997a0170026d5139c1" + `); + await queryRunner.query(` + ALTER TABLE "member_roles" DROP CONSTRAINT "FK_5d7ddc8a5f9c167f548625e772e" + `); + await queryRunner.query(` + ALTER TABLE "notes" DROP CONSTRAINT "FK_23e08e5b4481711d573e1abecdc" + `); + await queryRunner.query(` + ALTER TABLE "notes" DROP CONSTRAINT "FK_f9e103f8ae67cb1787063597925" + `); + await queryRunner.query(` + ALTER TABLE "sticker_packs" DROP CONSTRAINT "FK_448fafba4355ee1c837bbc865f1" + `); + await queryRunner.query(` + ALTER TABLE "sessions" DROP CONSTRAINT "FK_085d540d9f418cfbdc7bd55bb19" + `); + await queryRunner.query(` + ALTER TABLE "audit_logs" DROP CONSTRAINT "FK_bd2726fd31b35443f2245b93ba0" + `); + await queryRunner.query(` + ALTER TABLE "audit_logs" DROP CONSTRAINT "FK_3cd01cd3ae7aab010310d96ac8e" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" + `); + await queryRunner.query(` + ALTER TABLE "teams" DROP CONSTRAINT "FK_13f00abf7cb6096c43ecaf8c108" + `); + await queryRunner.query(` + ALTER TABLE "team_members" DROP CONSTRAINT "FK_c2bf4967c8c2a6b845dadfbf3d4" + `); + await queryRunner.query(` + ALTER TABLE "team_members" DROP CONSTRAINT "FK_fdad7d5768277e60c40e01cdcea" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_9d1d665379eefde7876a17afa99" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_95828668aa333460582e0ca6396" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" + `); + await queryRunner.query(` + ALTER TABLE "guilds" DROP CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" + `); + await queryRunner.query(` + ALTER TABLE "templates" DROP CONSTRAINT "FK_445d00eaaea0e60a017a5ed0c11" + `); + await queryRunner.query(` + ALTER TABLE "templates" DROP CONSTRAINT "FK_d7374b7f8f5fbfdececa4fb62e1" + `); + await queryRunner.query(` + ALTER TABLE "emojis" DROP CONSTRAINT "FK_fa7ddd5f9a214e28ce596548421" + `); + await queryRunner.query(` + ALTER TABLE "emojis" DROP CONSTRAINT "FK_4b988e0db89d94cebcf07f598cc" + `); + await queryRunner.query(` + ALTER TABLE "channels" DROP CONSTRAINT "FK_3873ed438575cce703ecff4fc7b" + `); + await queryRunner.query(` + ALTER TABLE "channels" DROP CONSTRAINT "FK_3274522d14af40540b1a883fc80" + `); + await queryRunner.query(` + ALTER TABLE "channels" DROP CONSTRAINT "FK_c253dafe5f3a03ec00cd8fb4581" + `); + await queryRunner.query(` + ALTER TABLE "voice_states" DROP CONSTRAINT "FK_5fe1d5f931a67e85039c640001b" + `); + await queryRunner.query(` + ALTER TABLE "voice_states" DROP CONSTRAINT "FK_9f8d389866b40b6657edd026dd4" + `); + await queryRunner.query(` + ALTER TABLE "voice_states" DROP CONSTRAINT "FK_03779ef216d4b0358470d9cb748" + `); + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" + `); + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" + `); + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" + `); + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" + `); + await queryRunner.query(` + ALTER TABLE "read_states" DROP CONSTRAINT "FK_195f92e4dd1254a4e348c043763" + `); + await queryRunner.query(` + ALTER TABLE "read_states" DROP CONSTRAINT "FK_40da2fca4e0eaf7a23b5bfc5d34" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_61a92bb65b302a76d9c1fcd3174" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_5d3ec1cb962de6488637fd779d6" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_f83c04bcf1df4e5c0e7a52ed348" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_b0525304f2262b7014245351c76" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_05535bc695e9f7ee104616459d3" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_b193588441b085352a4c0109423" + `); + await queryRunner.query(` + ALTER TABLE "messages" DROP CONSTRAINT "FK_86b9109b155eb70c0a2ca3b4b6d" + `); + await queryRunner.query(` + ALTER TABLE "attachments" DROP CONSTRAINT "FK_623e10eec51ada466c5038979e3" + `); + await queryRunner.query(` + ALTER TABLE "stickers" DROP CONSTRAINT "FK_8f4ee73f2bb2325ff980502e158" + `); + await queryRunner.query(` + ALTER TABLE "stickers" DROP CONSTRAINT "FK_193d551d852aca5347ef5c9f205" + `); + await queryRunner.query(` + ALTER TABLE "stickers" DROP CONSTRAINT "FK_e7cfa5cefa6661b3fb8fda8ce69" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" DROP CONSTRAINT "FK_3a285f4f49c40e0706d3018bc9f" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" DROP CONSTRAINT "FK_0d523f6f997c86e052c49b1455f" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" DROP CONSTRAINT "FK_c3e5305461931763b56aa905f1c" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" DROP CONSTRAINT "FK_df528cf77e82f8032230e7e37d8" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" DROP CONSTRAINT "FK_487a7af59d189f744fe394368fc" + `); + await queryRunner.query(` + ALTER TABLE "members" DROP CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" + `); + await queryRunner.query(` + ALTER TABLE "members" DROP CONSTRAINT "FK_28b53062261b996d9c99fa12404" + `); + await queryRunner.query(` + ALTER TABLE "roles" DROP CONSTRAINT "FK_c32c1ab1c4dc7dcb0278c4b1b8b" + `); + await queryRunner.query(` + ALTER TABLE "recipients" DROP CONSTRAINT "FK_6157e8b6ba4e6e3089616481fe2" + `); + await queryRunner.query(` + ALTER TABLE "recipients" DROP CONSTRAINT "FK_2f18ee1ba667f233ae86c0ea60e" + `); + await queryRunner.query(` + ALTER TABLE "bans" DROP CONSTRAINT "FK_07ad88c86d1f290d46748410d58" + `); + await queryRunner.query(` + ALTER TABLE "bans" DROP CONSTRAINT "FK_9d3ab7dd180ebdd245cdb66ecad" + `); + await queryRunner.query(` + ALTER TABLE "bans" DROP CONSTRAINT "FK_5999e8e449f80a236ff72023559" + `); + await queryRunner.query(` + ALTER TABLE "backup_codes" DROP CONSTRAINT "FK_70066ea80d2f4b871beda32633b" + `); + await queryRunner.query(` + ALTER TABLE "connected_accounts" DROP CONSTRAINT "FK_f47244225a6a1eac04a3463dd90" + `); + await queryRunner.query(` + ALTER TABLE "relationships" DROP CONSTRAINT "FK_9c7f6b98a9843b76dce1b0c878b" + `); + await queryRunner.query(` + ALTER TABLE "relationships" DROP CONSTRAINT "FK_9af4194bab1250b1c584ae4f1d7" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_e22a70819d07659c7a71c112a1" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_40bb6f23e7cc133292e92829d2" + `); + await queryRunner.query(` + DROP TABLE "message_stickers" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_bdb8c09e1464cabf62105bf4b9" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_2a27102ecd1d81b4582a436092" + `); + await queryRunner.query(` + DROP TABLE "message_channel_mentions" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_29d63eb1a458200851bc37d074" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_a8242cf535337a490b0feaea0b" + `); + await queryRunner.query(` + DROP TABLE "message_role_mentions" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_b831eb18ceebd28976239b1e2f" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_a343387fc560ef378760681c23" + `); + await queryRunner.query(` + DROP TABLE "message_user_mentions" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_e9080e7a7997a0170026d5139c" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_5d7ddc8a5f9c167f548625e772" + `); + await queryRunner.query(` + DROP TABLE "member_roles" + `); + await queryRunner.query(` + DROP TABLE "notes" + `); + await queryRunner.query(` + DROP TABLE "client_release" + `); + await queryRunner.query(` + DROP TABLE "sticker_packs" + `); + await queryRunner.query(` + DROP TABLE "sessions" + `); + await queryRunner.query(` + DROP TABLE "rate_limits" + `); + await queryRunner.query(` + DROP TABLE "categories" + `); + await queryRunner.query(` + DROP TABLE "audit_logs" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + DROP TABLE "teams" + `); + await queryRunner.query(` + DROP TABLE "team_members" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + DROP TABLE "templates" + `); + await queryRunner.query(` + DROP TABLE "emojis" + `); + await queryRunner.query(` + DROP TABLE "channels" + `); + await queryRunner.query(` + DROP TABLE "voice_states" + `); + await queryRunner.query(` + DROP TABLE "invites" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_0abf8b443321bd3cf7f81ee17a" + `); + await queryRunner.query(` + DROP TABLE "read_states" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_3ed7a60fb7dbe04e1ba9332a8b" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_05535bc695e9f7ee104616459d" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_86b9109b155eb70c0a2ca3b4b6" + `); + await queryRunner.query(` + DROP TABLE "messages" + `); + await queryRunner.query(` + DROP TABLE "attachments" + `); + await queryRunner.query(` + DROP TABLE "stickers" + `); + await queryRunner.query(` + DROP TABLE "webhooks" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + DROP TABLE "members" + `); + await queryRunner.query(` + DROP TABLE "roles" + `); + await queryRunner.query(` + DROP TABLE "recipients" + `); + await queryRunner.query(` + DROP TABLE "bans" + `); + await queryRunner.query(` + DROP TABLE "backup_codes" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + DROP TABLE "connected_accounts" + `); + await queryRunner.query(` + DROP INDEX "public"."IDX_a0b2ff0a598df0b0d055934a17" + `); + await queryRunner.query(` + DROP TABLE "relationships" + `); + await queryRunner.query(` + DROP TABLE "config" + `); + } +} diff --git a/src/util/migrations/postgres/1659921826567-premium_since_as_date.ts b/src/util/migrations/postgres/1659921826567-premium_since_as_date.ts new file mode 100644
index 00000000..7543ce85 --- /dev/null +++ b/src/util/migrations/postgres/1659921826567-premium_since_as_date.ts
@@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class premiumSinceAsDate1659921826567 implements MigrationInterface { + name = "premiumSinceAsDate1659921826567"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "members" DROP COLUMN "premium_since" + `); + await queryRunner.query(` + ALTER TABLE "members" + ADD "premium_since" TIMESTAMP + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "members" DROP COLUMN "premium_since" + `); + await queryRunner.query(` + ALTER TABLE "members" + ADD "premium_since" bigint + `); + } +} diff --git a/src/util/migrations/postgres/1660130561959-updated-applications.ts b/src/util/migrations/postgres/1660130561959-updated-applications.ts new file mode 100644
index 00000000..3d47d6d3 --- /dev/null +++ b/src/util/migrations/postgres/1660130561959-updated-applications.ts
@@ -0,0 +1,181 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class updatedApplications1660130561959 implements MigrationInterface { + name = "updatedApplications1660130561959"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "rpc_origins" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "primary_sku_id" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "slug" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "guild_id" + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "type" text + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "hook" boolean NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "redirect_uris" text + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "rpc_application_state" integer + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "store_application_state" integer + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "verification_state" integer + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "interactions_endpoint_url" character varying + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "integration_public" boolean + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "integration_require_code_grant" boolean + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "discoverability_state" integer + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "discovery_eligibility_flags" integer + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "tags" text + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "install_params" text + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "bot_user_id" character varying + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "UQ_2ce5a55796fe4c2f77ece57a647" UNIQUE ("bot_user_id") + `); + await queryRunner.query(` + ALTER TABLE "applications" + ALTER COLUMN "description" DROP NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "flags" + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "flags" integer NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "FK_2ce5a55796fe4c2f77ece57a647" FOREIGN KEY ("bot_user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "FK_2ce5a55796fe4c2f77ece57a647" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "flags" + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "flags" character varying NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "applications" + ALTER COLUMN "description" + SET NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP CONSTRAINT "UQ_2ce5a55796fe4c2f77ece57a647" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "bot_user_id" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "install_params" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "tags" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "discovery_eligibility_flags" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "discoverability_state" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "integration_require_code_grant" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "integration_public" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "interactions_endpoint_url" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "verification_state" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "store_application_state" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "rpc_application_state" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "redirect_uris" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "hook" + `); + await queryRunner.query(` + ALTER TABLE "applications" DROP COLUMN "type" + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "guild_id" character varying + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "slug" character varying + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "primary_sku_id" character varying + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD "rpc_origins" text + `); + await queryRunner.query(` + ALTER TABLE "applications" + ADD CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" FOREIGN KEY ("guild_id") REFERENCES "guilds"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } +} diff --git a/src/util/migrations/postgres/1660257815436-CodeCleanup2.ts b/src/util/migrations/postgres/1660257815436-CodeCleanup2.ts new file mode 100644
index 00000000..3e4167e9 --- /dev/null +++ b/src/util/migrations/postgres/1660257815436-CodeCleanup2.ts
@@ -0,0 +1,58 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup21660257815436 implements MigrationInterface { + name = "CodeCleanup21660257815436"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "user_settings" ( + "id" character varying NOT NULL, + "afk_timeout" integer, + "allow_accessibility_detection" boolean, + "animate_emoji" boolean, + "animate_stickers" integer, + "contact_sync_enabled" boolean, + "convert_emoticons" boolean, + "custom_status" text, + "default_guilds_restricted" boolean, + "detect_platform_accounts" boolean, + "developer_mode" boolean, + "disable_games_tab" boolean, + "enable_tts_command" boolean, + "explicit_content_filter" integer, + "friend_source_flags" text, + "gateway_connected" boolean, + "gif_auto_play" boolean, + "guild_folders" text, + "guild_positions" text, + "inline_attachment_media" boolean, + "inline_embed_media" boolean, + "locale" character varying, + "message_display_compact" boolean, + "native_phone_integration_enabled" boolean, + "render_embeds" boolean, + "render_reactions" boolean, + "restricted_guilds" text, + "show_current_game" boolean, + "status" character varying, + "stream_notifications_enabled" boolean, + "theme" character varying, + "timezone_offset" integer, + CONSTRAINT "PK_00f004f5922a0744d174530d639" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + ALTER TABLE "guilds" + ADD "premium_progress_bar_enabled" boolean + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "guilds" DROP COLUMN "premium_progress_bar_enabled" + `); + await queryRunner.query(` + DROP TABLE "user_settings" + `); + } +} diff --git a/src/util/migrations/postgres/1660258372154-CodeCleanup3.ts b/src/util/migrations/postgres/1660258372154-CodeCleanup3.ts new file mode 100644
index 00000000..3071b59f --- /dev/null +++ b/src/util/migrations/postgres/1660258372154-CodeCleanup3.ts
@@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup31660258372154 implements MigrationInterface { + name = "CodeCleanup31660258372154"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" DROP COLUMN "settings" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + ADD "settings" text NOT NULL + `); + } +} diff --git a/src/util/migrations/postgres/1660260565996-CodeCleanup4.ts b/src/util/migrations/postgres/1660260565996-CodeCleanup4.ts new file mode 100644
index 00000000..c2e9aa85 --- /dev/null +++ b/src/util/migrations/postgres/1660260565996-CodeCleanup4.ts
@@ -0,0 +1,32 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup41660260565996 implements MigrationInterface { + name = "CodeCleanup41660260565996"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + ADD "settingsId" character varying + `); + await queryRunner.query(` + ALTER TABLE "users" + ADD CONSTRAINT "UQ_76ba283779c8441fd5ff819c8cf" UNIQUE ("settingsId") + `); + await queryRunner.query(` + ALTER TABLE "users" + ADD CONSTRAINT "FK_76ba283779c8441fd5ff819c8cf" FOREIGN KEY ("settingsId") REFERENCES "user_settings"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" DROP CONSTRAINT "FK_76ba283779c8441fd5ff819c8cf" + `); + await queryRunner.query(` + ALTER TABLE "users" DROP CONSTRAINT "UQ_76ba283779c8441fd5ff819c8cf" + `); + await queryRunner.query(` + ALTER TABLE "users" DROP COLUMN "settingsId" + `); + } +} diff --git a/src/util/migrations/postgres/1660265907544-CodeCleanup5.ts b/src/util/migrations/postgres/1660265907544-CodeCleanup5.ts new file mode 100644
index 00000000..0f098e1f --- /dev/null +++ b/src/util/migrations/postgres/1660265907544-CodeCleanup5.ts
@@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup51660265907544 implements MigrationInterface { + name = "CodeCleanup51660265907544"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "channels" + ADD "flags" integer + `); + await queryRunner.query(` + ALTER TABLE "channels" + ADD "default_thread_rate_limit_per_user" integer + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "channels" DROP COLUMN "default_thread_rate_limit_per_user" + `); + await queryRunner.query(` + ALTER TABLE "channels" DROP COLUMN "flags" + `); + } +} diff --git a/src/util/migrations/postgres/1660416055566-InvitersAreDeletable.ts b/src/util/migrations/postgres/1660416055566-InvitersAreDeletable.ts new file mode 100644
index 00000000..e8321ede --- /dev/null +++ b/src/util/migrations/postgres/1660416055566-InvitersAreDeletable.ts
@@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class InvitersAreDeletable1660416055566 implements MigrationInterface { + name = "InvitersAreDeletable1660416055566"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "invites" DROP CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" + `); + await queryRunner.query(` + ALTER TABLE "invites" + ADD CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } +} diff --git a/src/util/migrations/postgres/1660549242936-fix_nullables.ts b/src/util/migrations/postgres/1660549242936-fix_nullables.ts new file mode 100644
index 00000000..07fd52f7 --- /dev/null +++ b/src/util/migrations/postgres/1660549242936-fix_nullables.ts
@@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class fixNullables1660549242936 implements MigrationInterface { + name = "fixNullables1660549242936"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + ALTER COLUMN "bio" DROP NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "users" + ALTER COLUMN "mfa_enabled" DROP NOT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + ALTER COLUMN "mfa_enabled" + SET NOT NULL + `); + await queryRunner.query(` + ALTER TABLE "users" + ALTER COLUMN "bio" + SET NOT NULL + `); + } +} diff --git a/src/util/migrations/sqlite/1659899662635-initial.ts b/src/util/migrations/sqlite/1659899662635-initial.ts new file mode 100644
index 00000000..dffaa51d --- /dev/null +++ b/src/util/migrations/sqlite/1659899662635-initial.ts
@@ -0,0 +1,3528 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class initial1659899662635 implements MigrationInterface { + name = "initial1659899662635"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "config" ("key" varchar PRIMARY KEY NOT NULL, "value" text) + `); + await queryRunner.query(` + CREATE TABLE "relationships" ( + "id" varchar PRIMARY KEY NOT NULL, + "from_id" varchar NOT NULL, + "to_id" varchar NOT NULL, + "nickname" varchar, + "type" integer NOT NULL + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_a0b2ff0a598df0b0d055934a17" ON "relationships" ("from_id", "to_id") + `); + await queryRunner.query(` + CREATE TABLE "connected_accounts" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "access_token" varchar NOT NULL, + "friend_sync" boolean NOT NULL, + "name" varchar NOT NULL, + "revoked" boolean NOT NULL, + "show_activity" boolean NOT NULL, + "type" varchar NOT NULL, + "verified" boolean NOT NULL, + "visibility" integer NOT NULL + ) + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "settings" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL + ) + `); + await queryRunner.query(` + CREATE TABLE "backup_codes" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "consumed" boolean NOT NULL, + "expired" boolean NOT NULL, + "user_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "bans" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "guild_id" varchar, + "executor_id" varchar, + "ip" varchar NOT NULL, + "reason" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "recipients" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "closed" boolean NOT NULL DEFAULT (0) + ) + `); + await queryRunner.query(` + CREATE TABLE "roles" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "color" integer NOT NULL, + "hoist" boolean NOT NULL, + "managed" boolean NOT NULL, + "mentionable" boolean NOT NULL, + "name" varchar NOT NULL, + "permissions" varchar NOT NULL, + "position" integer NOT NULL, + "icon" varchar, + "unicode_emoji" varchar, + "tags" text + ) + `); + await queryRunner.query(` + CREATE TABLE "members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + CREATE TABLE "webhooks" ( + "id" varchar PRIMARY KEY NOT NULL, + "type" integer NOT NULL, + "name" varchar, + "avatar" varchar, + "token" varchar, + "guild_id" varchar, + "channel_id" varchar, + "application_id" varchar, + "user_id" varchar, + "source_guild_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "stickers" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "available" boolean, + "tags" varchar, + "pack_id" varchar, + "guild_id" varchar, + "user_id" varchar, + "type" integer NOT NULL, + "format_type" integer NOT NULL + ) + `); + await queryRunner.query(` + CREATE TABLE "attachments" ( + "id" varchar PRIMARY KEY NOT NULL, + "filename" varchar NOT NULL, + "size" integer NOT NULL, + "url" varchar NOT NULL, + "proxy_url" varchar NOT NULL, + "height" integer, + "width" integer, + "content_type" varchar, + "message_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "messages" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar, + "guild_id" varchar, + "author_id" varchar, + "member_id" varchar, + "webhook_id" varchar, + "application_id" varchar, + "content" varchar, + "timestamp" datetime NOT NULL DEFAULT (datetime('now')), + "edited_timestamp" datetime, + "tts" boolean, + "mention_everyone" boolean, + "embeds" text NOT NULL, + "reactions" text NOT NULL, + "nonce" text, + "pinned" boolean, + "type" integer NOT NULL, + "activity" text, + "flags" varchar, + "message_reference" text, + "interaction" text, + "components" text, + "message_reference_id" varchar + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" ON "messages" ("channel_id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_05535bc695e9f7ee104616459d" ON "messages" ("author_id") + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" ON "messages" ("channel_id", "id") + `); + await queryRunner.query(` + CREATE TABLE "read_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "last_message_id" varchar, + "public_ack" varchar, + "notifications_cursor" varchar, + "last_pin_timestamp" datetime, + "mention_count" integer + ) + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_0abf8b443321bd3cf7f81ee17a" ON "read_states" ("channel_id", "user_id") + `); + await queryRunner.query(` + CREATE TABLE "invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean + ) + `); + await queryRunner.query(` + CREATE TABLE "voice_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "user_id" varchar, + "session_id" varchar NOT NULL, + "token" varchar, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "self_deaf" boolean NOT NULL, + "self_mute" boolean NOT NULL, + "self_stream" boolean, + "self_video" boolean NOT NULL, + "suppress" boolean NOT NULL, + "request_to_speak_timestamp" datetime + ) + `); + await queryRunner.query(` + CREATE TABLE "channels" ( + "id" varchar PRIMARY KEY NOT NULL, + "created_at" datetime NOT NULL, + "name" varchar, + "icon" text, + "type" integer NOT NULL, + "last_message_id" varchar, + "guild_id" varchar, + "parent_id" varchar, + "owner_id" varchar, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" varchar, + "retention_policy_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "emojis" ( + "id" varchar PRIMARY KEY NOT NULL, + "animated" boolean NOT NULL, + "available" boolean NOT NULL, + "guild_id" varchar NOT NULL, + "user_id" varchar, + "managed" boolean NOT NULL, + "name" varchar NOT NULL, + "require_colons" boolean NOT NULL, + "roles" text NOT NULL, + "groups" text + ) + `); + await queryRunner.query(` + CREATE TABLE "templates" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "usage_count" integer, + "creator_id" varchar, + "created_at" datetime NOT NULL, + "updated_at" datetime NOT NULL, + "source_guild_id" varchar, + "serialized_source_guild" text NOT NULL, + CONSTRAINT "UQ_be38737bf339baf63b1daeffb55" UNIQUE ("code") + ) + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "team_members" ( + "id" varchar PRIMARY KEY NOT NULL, + "membership_state" integer NOT NULL, + "permissions" text NOT NULL, + "team_id" varchar, + "user_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "teams" ( + "id" varchar PRIMARY KEY NOT NULL, + "icon" varchar, + "name" varchar NOT NULL, + "owner_user_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "audit_logs" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "action_type" integer NOT NULL, + "options" text, + "changes" text NOT NULL, + "reason" varchar, + "target_id" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "categories" ( + "id" integer PRIMARY KEY NOT NULL, + "name" varchar, + "localizations" text NOT NULL, + "is_primary" boolean + ) + `); + await queryRunner.query(` + CREATE TABLE "rate_limits" ( + "id" varchar PRIMARY KEY NOT NULL, + "executor_id" varchar NOT NULL, + "hits" integer NOT NULL, + "blocked" boolean NOT NULL, + "expires_at" datetime NOT NULL + ) + `); + await queryRunner.query(` + CREATE TABLE "sessions" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "session_id" varchar NOT NULL, + "activities" text, + "client_info" text NOT NULL, + "status" varchar NOT NULL + ) + `); + await queryRunner.query(` + CREATE TABLE "sticker_packs" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "banner_asset_id" varchar, + "cover_sticker_id" varchar, + "coverStickerId" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "client_release" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "pub_date" varchar NOT NULL, + "url" varchar NOT NULL, + "deb_url" varchar NOT NULL, + "osx_url" varchar NOT NULL, + "win_url" varchar NOT NULL, + "notes" varchar + ) + `); + await queryRunner.query(` + CREATE TABLE "notes" ( + "id" varchar PRIMARY KEY NOT NULL, + "content" varchar NOT NULL, + "owner_id" varchar, + "target_id" varchar, + CONSTRAINT "UQ_74e6689b9568cc965b8bfc9150b" UNIQUE ("owner_id", "target_id") + ) + `); + await queryRunner.query(` + CREATE TABLE "member_roles" ( + "index" integer NOT NULL, + "role_id" varchar NOT NULL, + PRIMARY KEY ("index", "role_id") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_5d7ddc8a5f9c167f548625e772" ON "member_roles" ("index") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e9080e7a7997a0170026d5139c" ON "member_roles" ("role_id") + `); + await queryRunner.query(` + CREATE TABLE "message_user_mentions" ( + "messagesId" varchar NOT NULL, + "usersId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "usersId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_a343387fc560ef378760681c23" ON "message_user_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_b831eb18ceebd28976239b1e2f" ON "message_user_mentions" ("usersId") + `); + await queryRunner.query(` + CREATE TABLE "message_role_mentions" ( + "messagesId" varchar NOT NULL, + "rolesId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "rolesId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_a8242cf535337a490b0feaea0b" ON "message_role_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_29d63eb1a458200851bc37d074" ON "message_role_mentions" ("rolesId") + `); + await queryRunner.query(` + CREATE TABLE "message_channel_mentions" ( + "messagesId" varchar NOT NULL, + "channelsId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "channelsId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_2a27102ecd1d81b4582a436092" ON "message_channel_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_bdb8c09e1464cabf62105bf4b9" ON "message_channel_mentions" ("channelsId") + `); + await queryRunner.query(` + CREATE TABLE "message_stickers" ( + "messagesId" varchar NOT NULL, + "stickersId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "stickersId") + ) + `); + await queryRunner.query(` + CREATE INDEX "IDX_40bb6f23e7cc133292e92829d2" ON "message_stickers" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e22a70819d07659c7a71c112a1" ON "message_stickers" ("stickersId") + `); + await queryRunner.query(` + DROP INDEX "IDX_a0b2ff0a598df0b0d055934a17" + `); + await queryRunner.query(` + CREATE TABLE "temporary_relationships" ( + "id" varchar PRIMARY KEY NOT NULL, + "from_id" varchar NOT NULL, + "to_id" varchar NOT NULL, + "nickname" varchar, + "type" integer NOT NULL, + CONSTRAINT "FK_9af4194bab1250b1c584ae4f1d7" FOREIGN KEY ("from_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_9c7f6b98a9843b76dce1b0c878b" FOREIGN KEY ("to_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_relationships"("id", "from_id", "to_id", "nickname", "type") + SELECT "id", + "from_id", + "to_id", + "nickname", + "type" + FROM "relationships" + `); + await queryRunner.query(` + DROP TABLE "relationships" + `); + await queryRunner.query(` + ALTER TABLE "temporary_relationships" + RENAME TO "relationships" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_a0b2ff0a598df0b0d055934a17" ON "relationships" ("from_id", "to_id") + `); + await queryRunner.query(` + CREATE TABLE "temporary_connected_accounts" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "access_token" varchar NOT NULL, + "friend_sync" boolean NOT NULL, + "name" varchar NOT NULL, + "revoked" boolean NOT NULL, + "show_activity" boolean NOT NULL, + "type" varchar NOT NULL, + "verified" boolean NOT NULL, + "visibility" integer NOT NULL, + CONSTRAINT "FK_f47244225a6a1eac04a3463dd90" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_connected_accounts"( + "id", + "user_id", + "access_token", + "friend_sync", + "name", + "revoked", + "show_activity", + "type", + "verified", + "visibility" + ) + SELECT "id", + "user_id", + "access_token", + "friend_sync", + "name", + "revoked", + "show_activity", + "type", + "verified", + "visibility" + FROM "connected_accounts" + `); + await queryRunner.query(` + DROP TABLE "connected_accounts" + `); + await queryRunner.query(` + ALTER TABLE "temporary_connected_accounts" + RENAME TO "connected_accounts" + `); + await queryRunner.query(` + CREATE TABLE "temporary_backup_codes" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "consumed" boolean NOT NULL, + "expired" boolean NOT NULL, + "user_id" varchar, + CONSTRAINT "FK_70066ea80d2f4b871beda32633b" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_backup_codes"("id", "code", "consumed", "expired", "user_id") + SELECT "id", + "code", + "consumed", + "expired", + "user_id" + FROM "backup_codes" + `); + await queryRunner.query(` + DROP TABLE "backup_codes" + `); + await queryRunner.query(` + ALTER TABLE "temporary_backup_codes" + RENAME TO "backup_codes" + `); + await queryRunner.query(` + CREATE TABLE "temporary_bans" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "guild_id" varchar, + "executor_id" varchar, + "ip" varchar NOT NULL, + "reason" varchar, + CONSTRAINT "FK_5999e8e449f80a236ff72023559" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_9d3ab7dd180ebdd245cdb66ecad" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_07ad88c86d1f290d46748410d58" FOREIGN KEY ("executor_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_bans"( + "id", + "user_id", + "guild_id", + "executor_id", + "ip", + "reason" + ) + SELECT "id", + "user_id", + "guild_id", + "executor_id", + "ip", + "reason" + FROM "bans" + `); + await queryRunner.query(` + DROP TABLE "bans" + `); + await queryRunner.query(` + ALTER TABLE "temporary_bans" + RENAME TO "bans" + `); + await queryRunner.query(` + CREATE TABLE "temporary_recipients" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "closed" boolean NOT NULL DEFAULT (0), + CONSTRAINT "FK_2f18ee1ba667f233ae86c0ea60e" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_6157e8b6ba4e6e3089616481fe2" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_recipients"("id", "channel_id", "user_id", "closed") + SELECT "id", + "channel_id", + "user_id", + "closed" + FROM "recipients" + `); + await queryRunner.query(` + DROP TABLE "recipients" + `); + await queryRunner.query(` + ALTER TABLE "temporary_recipients" + RENAME TO "recipients" + `); + await queryRunner.query(` + CREATE TABLE "temporary_roles" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "color" integer NOT NULL, + "hoist" boolean NOT NULL, + "managed" boolean NOT NULL, + "mentionable" boolean NOT NULL, + "name" varchar NOT NULL, + "permissions" varchar NOT NULL, + "position" integer NOT NULL, + "icon" varchar, + "unicode_emoji" varchar, + "tags" text, + CONSTRAINT "FK_c32c1ab1c4dc7dcb0278c4b1b8b" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_roles"( + "id", + "guild_id", + "color", + "hoist", + "managed", + "mentionable", + "name", + "permissions", + "position", + "icon", + "unicode_emoji", + "tags" + ) + SELECT "id", + "guild_id", + "color", + "hoist", + "managed", + "mentionable", + "name", + "permissions", + "position", + "icon", + "unicode_emoji", + "tags" + FROM "roles" + `); + await queryRunner.query(` + DROP TABLE "roles" + `); + await queryRunner.query(` + ALTER TABLE "temporary_roles" + RENAME TO "roles" + `); + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + CREATE TABLE "temporary_members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar, + CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "members" + `); + await queryRunner.query(` + DROP TABLE "members" + `); + await queryRunner.query(` + ALTER TABLE "temporary_members" + RENAME TO "members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + CREATE TABLE "temporary_webhooks" ( + "id" varchar PRIMARY KEY NOT NULL, + "type" integer NOT NULL, + "name" varchar, + "avatar" varchar, + "token" varchar, + "guild_id" varchar, + "channel_id" varchar, + "application_id" varchar, + "user_id" varchar, + "source_guild_id" varchar, + CONSTRAINT "FK_487a7af59d189f744fe394368fc" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_df528cf77e82f8032230e7e37d8" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_c3e5305461931763b56aa905f1c" FOREIGN KEY ("application_id") REFERENCES "applications" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_0d523f6f997c86e052c49b1455f" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3a285f4f49c40e0706d3018bc9f" FOREIGN KEY ("source_guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_webhooks"( + "id", + "type", + "name", + "avatar", + "token", + "guild_id", + "channel_id", + "application_id", + "user_id", + "source_guild_id" + ) + SELECT "id", + "type", + "name", + "avatar", + "token", + "guild_id", + "channel_id", + "application_id", + "user_id", + "source_guild_id" + FROM "webhooks" + `); + await queryRunner.query(` + DROP TABLE "webhooks" + `); + await queryRunner.query(` + ALTER TABLE "temporary_webhooks" + RENAME TO "webhooks" + `); + await queryRunner.query(` + CREATE TABLE "temporary_stickers" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "available" boolean, + "tags" varchar, + "pack_id" varchar, + "guild_id" varchar, + "user_id" varchar, + "type" integer NOT NULL, + "format_type" integer NOT NULL, + CONSTRAINT "FK_e7cfa5cefa6661b3fb8fda8ce69" FOREIGN KEY ("pack_id") REFERENCES "sticker_packs" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_193d551d852aca5347ef5c9f205" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_8f4ee73f2bb2325ff980502e158" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_stickers"( + "id", + "name", + "description", + "available", + "tags", + "pack_id", + "guild_id", + "user_id", + "type", + "format_type" + ) + SELECT "id", + "name", + "description", + "available", + "tags", + "pack_id", + "guild_id", + "user_id", + "type", + "format_type" + FROM "stickers" + `); + await queryRunner.query(` + DROP TABLE "stickers" + `); + await queryRunner.query(` + ALTER TABLE "temporary_stickers" + RENAME TO "stickers" + `); + await queryRunner.query(` + CREATE TABLE "temporary_attachments" ( + "id" varchar PRIMARY KEY NOT NULL, + "filename" varchar NOT NULL, + "size" integer NOT NULL, + "url" varchar NOT NULL, + "proxy_url" varchar NOT NULL, + "height" integer, + "width" integer, + "content_type" varchar, + "message_id" varchar, + CONSTRAINT "FK_623e10eec51ada466c5038979e3" FOREIGN KEY ("message_id") REFERENCES "messages" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_attachments"( + "id", + "filename", + "size", + "url", + "proxy_url", + "height", + "width", + "content_type", + "message_id" + ) + SELECT "id", + "filename", + "size", + "url", + "proxy_url", + "height", + "width", + "content_type", + "message_id" + FROM "attachments" + `); + await queryRunner.query(` + DROP TABLE "attachments" + `); + await queryRunner.query(` + ALTER TABLE "temporary_attachments" + RENAME TO "attachments" + `); + await queryRunner.query(` + DROP INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" + `); + await queryRunner.query(` + DROP INDEX "IDX_05535bc695e9f7ee104616459d" + `); + await queryRunner.query(` + DROP INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" + `); + await queryRunner.query(` + CREATE TABLE "temporary_messages" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar, + "guild_id" varchar, + "author_id" varchar, + "member_id" varchar, + "webhook_id" varchar, + "application_id" varchar, + "content" varchar, + "timestamp" datetime NOT NULL DEFAULT (datetime('now')), + "edited_timestamp" datetime, + "tts" boolean, + "mention_everyone" boolean, + "embeds" text NOT NULL, + "reactions" text NOT NULL, + "nonce" text, + "pinned" boolean, + "type" integer NOT NULL, + "activity" text, + "flags" varchar, + "message_reference" text, + "interaction" text, + "components" text, + "message_reference_id" varchar, + CONSTRAINT "FK_86b9109b155eb70c0a2ca3b4b6d" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_b193588441b085352a4c0109423" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_05535bc695e9f7ee104616459d3" FOREIGN KEY ("author_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_b0525304f2262b7014245351c76" FOREIGN KEY ("member_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_f83c04bcf1df4e5c0e7a52ed348" FOREIGN KEY ("webhook_id") REFERENCES "webhooks" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_5d3ec1cb962de6488637fd779d6" FOREIGN KEY ("application_id") REFERENCES "applications" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_61a92bb65b302a76d9c1fcd3174" FOREIGN KEY ("message_reference_id") REFERENCES "messages" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_messages"( + "id", + "channel_id", + "guild_id", + "author_id", + "member_id", + "webhook_id", + "application_id", + "content", + "timestamp", + "edited_timestamp", + "tts", + "mention_everyone", + "embeds", + "reactions", + "nonce", + "pinned", + "type", + "activity", + "flags", + "message_reference", + "interaction", + "components", + "message_reference_id" + ) + SELECT "id", + "channel_id", + "guild_id", + "author_id", + "member_id", + "webhook_id", + "application_id", + "content", + "timestamp", + "edited_timestamp", + "tts", + "mention_everyone", + "embeds", + "reactions", + "nonce", + "pinned", + "type", + "activity", + "flags", + "message_reference", + "interaction", + "components", + "message_reference_id" + FROM "messages" + `); + await queryRunner.query(` + DROP TABLE "messages" + `); + await queryRunner.query(` + ALTER TABLE "temporary_messages" + RENAME TO "messages" + `); + await queryRunner.query(` + CREATE INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" ON "messages" ("channel_id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_05535bc695e9f7ee104616459d" ON "messages" ("author_id") + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" ON "messages" ("channel_id", "id") + `); + await queryRunner.query(` + DROP INDEX "IDX_0abf8b443321bd3cf7f81ee17a" + `); + await queryRunner.query(` + CREATE TABLE "temporary_read_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "last_message_id" varchar, + "public_ack" varchar, + "notifications_cursor" varchar, + "last_pin_timestamp" datetime, + "mention_count" integer, + CONSTRAINT "FK_40da2fca4e0eaf7a23b5bfc5d34" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_195f92e4dd1254a4e348c043763" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_read_states"( + "id", + "channel_id", + "user_id", + "last_message_id", + "public_ack", + "notifications_cursor", + "last_pin_timestamp", + "mention_count" + ) + SELECT "id", + "channel_id", + "user_id", + "last_message_id", + "public_ack", + "notifications_cursor", + "last_pin_timestamp", + "mention_count" + FROM "read_states" + `); + await queryRunner.query(` + DROP TABLE "read_states" + `); + await queryRunner.query(` + ALTER TABLE "temporary_read_states" + RENAME TO "read_states" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_0abf8b443321bd3cf7f81ee17a" ON "read_states" ("channel_id", "user_id") + `); + await queryRunner.query(` + CREATE TABLE "temporary_invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "invites" + `); + await queryRunner.query(` + DROP TABLE "invites" + `); + await queryRunner.query(` + ALTER TABLE "temporary_invites" + RENAME TO "invites" + `); + await queryRunner.query(` + CREATE TABLE "temporary_voice_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "user_id" varchar, + "session_id" varchar NOT NULL, + "token" varchar, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "self_deaf" boolean NOT NULL, + "self_mute" boolean NOT NULL, + "self_stream" boolean, + "self_video" boolean NOT NULL, + "suppress" boolean NOT NULL, + "request_to_speak_timestamp" datetime, + CONSTRAINT "FK_03779ef216d4b0358470d9cb748" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_9f8d389866b40b6657edd026dd4" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_5fe1d5f931a67e85039c640001b" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_voice_states"( + "id", + "guild_id", + "channel_id", + "user_id", + "session_id", + "token", + "deaf", + "mute", + "self_deaf", + "self_mute", + "self_stream", + "self_video", + "suppress", + "request_to_speak_timestamp" + ) + SELECT "id", + "guild_id", + "channel_id", + "user_id", + "session_id", + "token", + "deaf", + "mute", + "self_deaf", + "self_mute", + "self_stream", + "self_video", + "suppress", + "request_to_speak_timestamp" + FROM "voice_states" + `); + await queryRunner.query(` + DROP TABLE "voice_states" + `); + await queryRunner.query(` + ALTER TABLE "temporary_voice_states" + RENAME TO "voice_states" + `); + await queryRunner.query(` + CREATE TABLE "temporary_channels" ( + "id" varchar PRIMARY KEY NOT NULL, + "created_at" datetime NOT NULL, + "name" varchar, + "icon" text, + "type" integer NOT NULL, + "last_message_id" varchar, + "guild_id" varchar, + "parent_id" varchar, + "owner_id" varchar, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" varchar, + "retention_policy_id" varchar, + CONSTRAINT "FK_c253dafe5f3a03ec00cd8fb4581" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3274522d14af40540b1a883fc80" FOREIGN KEY ("parent_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_3873ed438575cce703ecff4fc7b" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_channels"( + "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + ) + SELECT "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + FROM "channels" + `); + await queryRunner.query(` + DROP TABLE "channels" + `); + await queryRunner.query(` + ALTER TABLE "temporary_channels" + RENAME TO "channels" + `); + await queryRunner.query(` + CREATE TABLE "temporary_emojis" ( + "id" varchar PRIMARY KEY NOT NULL, + "animated" boolean NOT NULL, + "available" boolean NOT NULL, + "guild_id" varchar NOT NULL, + "user_id" varchar, + "managed" boolean NOT NULL, + "name" varchar NOT NULL, + "require_colons" boolean NOT NULL, + "roles" text NOT NULL, + "groups" text, + CONSTRAINT "FK_4b988e0db89d94cebcf07f598cc" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_fa7ddd5f9a214e28ce596548421" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_emojis"( + "id", + "animated", + "available", + "guild_id", + "user_id", + "managed", + "name", + "require_colons", + "roles", + "groups" + ) + SELECT "id", + "animated", + "available", + "guild_id", + "user_id", + "managed", + "name", + "require_colons", + "roles", + "groups" + FROM "emojis" + `); + await queryRunner.query(` + DROP TABLE "emojis" + `); + await queryRunner.query(` + ALTER TABLE "temporary_emojis" + RENAME TO "emojis" + `); + await queryRunner.query(` + CREATE TABLE "temporary_templates" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "usage_count" integer, + "creator_id" varchar, + "created_at" datetime NOT NULL, + "updated_at" datetime NOT NULL, + "source_guild_id" varchar, + "serialized_source_guild" text NOT NULL, + CONSTRAINT "UQ_be38737bf339baf63b1daeffb55" UNIQUE ("code"), + CONSTRAINT "FK_d7374b7f8f5fbfdececa4fb62e1" FOREIGN KEY ("creator_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_445d00eaaea0e60a017a5ed0c11" FOREIGN KEY ("source_guild_id") REFERENCES "guilds" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_templates"( + "id", + "code", + "name", + "description", + "usage_count", + "creator_id", + "created_at", + "updated_at", + "source_guild_id", + "serialized_source_guild" + ) + SELECT "id", + "code", + "name", + "description", + "usage_count", + "creator_id", + "created_at", + "updated_at", + "source_guild_id", + "serialized_source_guild" + FROM "templates" + `); + await queryRunner.query(` + DROP TABLE "templates" + `); + await queryRunner.query(` + ALTER TABLE "temporary_templates" + RENAME TO "templates" + `); + await queryRunner.query(` + CREATE TABLE "temporary_guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + FROM "guilds" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + ALTER TABLE "temporary_guilds" + RENAME TO "guilds" + `); + await queryRunner.query(` + CREATE TABLE "temporary_team_members" ( + "id" varchar PRIMARY KEY NOT NULL, + "membership_state" integer NOT NULL, + "permissions" text NOT NULL, + "team_id" varchar, + "user_id" varchar, + CONSTRAINT "FK_fdad7d5768277e60c40e01cdcea" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_c2bf4967c8c2a6b845dadfbf3d4" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_team_members"( + "id", + "membership_state", + "permissions", + "team_id", + "user_id" + ) + SELECT "id", + "membership_state", + "permissions", + "team_id", + "user_id" + FROM "team_members" + `); + await queryRunner.query(` + DROP TABLE "team_members" + `); + await queryRunner.query(` + ALTER TABLE "temporary_team_members" + RENAME TO "team_members" + `); + await queryRunner.query(` + CREATE TABLE "temporary_teams" ( + "id" varchar PRIMARY KEY NOT NULL, + "icon" varchar, + "name" varchar NOT NULL, + "owner_user_id" varchar, + CONSTRAINT "FK_13f00abf7cb6096c43ecaf8c108" FOREIGN KEY ("owner_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_teams"("id", "icon", "name", "owner_user_id") + SELECT "id", + "icon", + "name", + "owner_user_id" + FROM "teams" + `); + await queryRunner.query(` + DROP TABLE "teams" + `); + await queryRunner.query(` + ALTER TABLE "temporary_teams" + RENAME TO "teams" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_audit_logs" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "action_type" integer NOT NULL, + "options" text, + "changes" text NOT NULL, + "reason" varchar, + "target_id" varchar, + CONSTRAINT "FK_3cd01cd3ae7aab010310d96ac8e" FOREIGN KEY ("target_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_bd2726fd31b35443f2245b93ba0" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_audit_logs"( + "id", + "user_id", + "action_type", + "options", + "changes", + "reason", + "target_id" + ) + SELECT "id", + "user_id", + "action_type", + "options", + "changes", + "reason", + "target_id" + FROM "audit_logs" + `); + await queryRunner.query(` + DROP TABLE "audit_logs" + `); + await queryRunner.query(` + ALTER TABLE "temporary_audit_logs" + RENAME TO "audit_logs" + `); + await queryRunner.query(` + CREATE TABLE "temporary_sessions" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "session_id" varchar NOT NULL, + "activities" text, + "client_info" text NOT NULL, + "status" varchar NOT NULL, + CONSTRAINT "FK_085d540d9f418cfbdc7bd55bb19" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_sessions"( + "id", + "user_id", + "session_id", + "activities", + "client_info", + "status" + ) + SELECT "id", + "user_id", + "session_id", + "activities", + "client_info", + "status" + FROM "sessions" + `); + await queryRunner.query(` + DROP TABLE "sessions" + `); + await queryRunner.query(` + ALTER TABLE "temporary_sessions" + RENAME TO "sessions" + `); + await queryRunner.query(` + CREATE TABLE "temporary_sticker_packs" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "banner_asset_id" varchar, + "cover_sticker_id" varchar, + "coverStickerId" varchar, + CONSTRAINT "FK_448fafba4355ee1c837bbc865f1" FOREIGN KEY ("coverStickerId") REFERENCES "stickers" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_sticker_packs"( + "id", + "name", + "description", + "banner_asset_id", + "cover_sticker_id", + "coverStickerId" + ) + SELECT "id", + "name", + "description", + "banner_asset_id", + "cover_sticker_id", + "coverStickerId" + FROM "sticker_packs" + `); + await queryRunner.query(` + DROP TABLE "sticker_packs" + `); + await queryRunner.query(` + ALTER TABLE "temporary_sticker_packs" + RENAME TO "sticker_packs" + `); + await queryRunner.query(` + CREATE TABLE "temporary_notes" ( + "id" varchar PRIMARY KEY NOT NULL, + "content" varchar NOT NULL, + "owner_id" varchar, + "target_id" varchar, + CONSTRAINT "UQ_74e6689b9568cc965b8bfc9150b" UNIQUE ("owner_id", "target_id"), + CONSTRAINT "FK_f9e103f8ae67cb1787063597925" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_23e08e5b4481711d573e1abecdc" FOREIGN KEY ("target_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_notes"("id", "content", "owner_id", "target_id") + SELECT "id", + "content", + "owner_id", + "target_id" + FROM "notes" + `); + await queryRunner.query(` + DROP TABLE "notes" + `); + await queryRunner.query(` + ALTER TABLE "temporary_notes" + RENAME TO "notes" + `); + await queryRunner.query(` + DROP INDEX "IDX_5d7ddc8a5f9c167f548625e772" + `); + await queryRunner.query(` + DROP INDEX "IDX_e9080e7a7997a0170026d5139c" + `); + await queryRunner.query(` + CREATE TABLE "temporary_member_roles" ( + "index" integer NOT NULL, + "role_id" varchar NOT NULL, + CONSTRAINT "FK_5d7ddc8a5f9c167f548625e772e" FOREIGN KEY ("index") REFERENCES "members" ("index") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_e9080e7a7997a0170026d5139c1" FOREIGN KEY ("role_id") REFERENCES "roles" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY ("index", "role_id") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_member_roles"("index", "role_id") + SELECT "index", + "role_id" + FROM "member_roles" + `); + await queryRunner.query(` + DROP TABLE "member_roles" + `); + await queryRunner.query(` + ALTER TABLE "temporary_member_roles" + RENAME TO "member_roles" + `); + await queryRunner.query(` + CREATE INDEX "IDX_5d7ddc8a5f9c167f548625e772" ON "member_roles" ("index") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e9080e7a7997a0170026d5139c" ON "member_roles" ("role_id") + `); + await queryRunner.query(` + DROP INDEX "IDX_a343387fc560ef378760681c23" + `); + await queryRunner.query(` + DROP INDEX "IDX_b831eb18ceebd28976239b1e2f" + `); + await queryRunner.query(` + CREATE TABLE "temporary_message_user_mentions" ( + "messagesId" varchar NOT NULL, + "usersId" varchar NOT NULL, + CONSTRAINT "FK_a343387fc560ef378760681c236" FOREIGN KEY ("messagesId") REFERENCES "messages" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_b831eb18ceebd28976239b1e2f8" FOREIGN KEY ("usersId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY ("messagesId", "usersId") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_message_user_mentions"("messagesId", "usersId") + SELECT "messagesId", + "usersId" + FROM "message_user_mentions" + `); + await queryRunner.query(` + DROP TABLE "message_user_mentions" + `); + await queryRunner.query(` + ALTER TABLE "temporary_message_user_mentions" + RENAME TO "message_user_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_a343387fc560ef378760681c23" ON "message_user_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_b831eb18ceebd28976239b1e2f" ON "message_user_mentions" ("usersId") + `); + await queryRunner.query(` + DROP INDEX "IDX_a8242cf535337a490b0feaea0b" + `); + await queryRunner.query(` + DROP INDEX "IDX_29d63eb1a458200851bc37d074" + `); + await queryRunner.query(` + CREATE TABLE "temporary_message_role_mentions" ( + "messagesId" varchar NOT NULL, + "rolesId" varchar NOT NULL, + CONSTRAINT "FK_a8242cf535337a490b0feaea0b4" FOREIGN KEY ("messagesId") REFERENCES "messages" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_29d63eb1a458200851bc37d074b" FOREIGN KEY ("rolesId") REFERENCES "roles" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY ("messagesId", "rolesId") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_message_role_mentions"("messagesId", "rolesId") + SELECT "messagesId", + "rolesId" + FROM "message_role_mentions" + `); + await queryRunner.query(` + DROP TABLE "message_role_mentions" + `); + await queryRunner.query(` + ALTER TABLE "temporary_message_role_mentions" + RENAME TO "message_role_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_a8242cf535337a490b0feaea0b" ON "message_role_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_29d63eb1a458200851bc37d074" ON "message_role_mentions" ("rolesId") + `); + await queryRunner.query(` + DROP INDEX "IDX_2a27102ecd1d81b4582a436092" + `); + await queryRunner.query(` + DROP INDEX "IDX_bdb8c09e1464cabf62105bf4b9" + `); + await queryRunner.query(` + CREATE TABLE "temporary_message_channel_mentions" ( + "messagesId" varchar NOT NULL, + "channelsId" varchar NOT NULL, + CONSTRAINT "FK_2a27102ecd1d81b4582a4360921" FOREIGN KEY ("messagesId") REFERENCES "messages" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_bdb8c09e1464cabf62105bf4b9d" FOREIGN KEY ("channelsId") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY ("messagesId", "channelsId") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_message_channel_mentions"("messagesId", "channelsId") + SELECT "messagesId", + "channelsId" + FROM "message_channel_mentions" + `); + await queryRunner.query(` + DROP TABLE "message_channel_mentions" + `); + await queryRunner.query(` + ALTER TABLE "temporary_message_channel_mentions" + RENAME TO "message_channel_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_2a27102ecd1d81b4582a436092" ON "message_channel_mentions" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_bdb8c09e1464cabf62105bf4b9" ON "message_channel_mentions" ("channelsId") + `); + await queryRunner.query(` + DROP INDEX "IDX_40bb6f23e7cc133292e92829d2" + `); + await queryRunner.query(` + DROP INDEX "IDX_e22a70819d07659c7a71c112a1" + `); + await queryRunner.query(` + CREATE TABLE "temporary_message_stickers" ( + "messagesId" varchar NOT NULL, + "stickersId" varchar NOT NULL, + CONSTRAINT "FK_40bb6f23e7cc133292e92829d28" FOREIGN KEY ("messagesId") REFERENCES "messages" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "FK_e22a70819d07659c7a71c112a1f" FOREIGN KEY ("stickersId") REFERENCES "stickers" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY ("messagesId", "stickersId") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_message_stickers"("messagesId", "stickersId") + SELECT "messagesId", + "stickersId" + FROM "message_stickers" + `); + await queryRunner.query(` + DROP TABLE "message_stickers" + `); + await queryRunner.query(` + ALTER TABLE "temporary_message_stickers" + RENAME TO "message_stickers" + `); + await queryRunner.query(` + CREATE INDEX "IDX_40bb6f23e7cc133292e92829d2" ON "message_stickers" ("messagesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_e22a70819d07659c7a71c112a1" ON "message_stickers" ("stickersId") + `); + await queryRunner.query(` + CREATE TABLE "query-result-cache" ( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "identifier" varchar, + "time" bigint NOT NULL, + "duration" integer NOT NULL, + "query" text NOT NULL, + "result" text NOT NULL + ) + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP TABLE "query-result-cache" + `); + await queryRunner.query(` + DROP INDEX "IDX_e22a70819d07659c7a71c112a1" + `); + await queryRunner.query(` + DROP INDEX "IDX_40bb6f23e7cc133292e92829d2" + `); + await queryRunner.query(` + ALTER TABLE "message_stickers" + RENAME TO "temporary_message_stickers" + `); + await queryRunner.query(` + CREATE TABLE "message_stickers" ( + "messagesId" varchar NOT NULL, + "stickersId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "stickersId") + ) + `); + await queryRunner.query(` + INSERT INTO "message_stickers"("messagesId", "stickersId") + SELECT "messagesId", + "stickersId" + FROM "temporary_message_stickers" + `); + await queryRunner.query(` + DROP TABLE "temporary_message_stickers" + `); + await queryRunner.query(` + CREATE INDEX "IDX_e22a70819d07659c7a71c112a1" ON "message_stickers" ("stickersId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_40bb6f23e7cc133292e92829d2" ON "message_stickers" ("messagesId") + `); + await queryRunner.query(` + DROP INDEX "IDX_bdb8c09e1464cabf62105bf4b9" + `); + await queryRunner.query(` + DROP INDEX "IDX_2a27102ecd1d81b4582a436092" + `); + await queryRunner.query(` + ALTER TABLE "message_channel_mentions" + RENAME TO "temporary_message_channel_mentions" + `); + await queryRunner.query(` + CREATE TABLE "message_channel_mentions" ( + "messagesId" varchar NOT NULL, + "channelsId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "channelsId") + ) + `); + await queryRunner.query(` + INSERT INTO "message_channel_mentions"("messagesId", "channelsId") + SELECT "messagesId", + "channelsId" + FROM "temporary_message_channel_mentions" + `); + await queryRunner.query(` + DROP TABLE "temporary_message_channel_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_bdb8c09e1464cabf62105bf4b9" ON "message_channel_mentions" ("channelsId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_2a27102ecd1d81b4582a436092" ON "message_channel_mentions" ("messagesId") + `); + await queryRunner.query(` + DROP INDEX "IDX_29d63eb1a458200851bc37d074" + `); + await queryRunner.query(` + DROP INDEX "IDX_a8242cf535337a490b0feaea0b" + `); + await queryRunner.query(` + ALTER TABLE "message_role_mentions" + RENAME TO "temporary_message_role_mentions" + `); + await queryRunner.query(` + CREATE TABLE "message_role_mentions" ( + "messagesId" varchar NOT NULL, + "rolesId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "rolesId") + ) + `); + await queryRunner.query(` + INSERT INTO "message_role_mentions"("messagesId", "rolesId") + SELECT "messagesId", + "rolesId" + FROM "temporary_message_role_mentions" + `); + await queryRunner.query(` + DROP TABLE "temporary_message_role_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_29d63eb1a458200851bc37d074" ON "message_role_mentions" ("rolesId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_a8242cf535337a490b0feaea0b" ON "message_role_mentions" ("messagesId") + `); + await queryRunner.query(` + DROP INDEX "IDX_b831eb18ceebd28976239b1e2f" + `); + await queryRunner.query(` + DROP INDEX "IDX_a343387fc560ef378760681c23" + `); + await queryRunner.query(` + ALTER TABLE "message_user_mentions" + RENAME TO "temporary_message_user_mentions" + `); + await queryRunner.query(` + CREATE TABLE "message_user_mentions" ( + "messagesId" varchar NOT NULL, + "usersId" varchar NOT NULL, + PRIMARY KEY ("messagesId", "usersId") + ) + `); + await queryRunner.query(` + INSERT INTO "message_user_mentions"("messagesId", "usersId") + SELECT "messagesId", + "usersId" + FROM "temporary_message_user_mentions" + `); + await queryRunner.query(` + DROP TABLE "temporary_message_user_mentions" + `); + await queryRunner.query(` + CREATE INDEX "IDX_b831eb18ceebd28976239b1e2f" ON "message_user_mentions" ("usersId") + `); + await queryRunner.query(` + CREATE INDEX "IDX_a343387fc560ef378760681c23" ON "message_user_mentions" ("messagesId") + `); + await queryRunner.query(` + DROP INDEX "IDX_e9080e7a7997a0170026d5139c" + `); + await queryRunner.query(` + DROP INDEX "IDX_5d7ddc8a5f9c167f548625e772" + `); + await queryRunner.query(` + ALTER TABLE "member_roles" + RENAME TO "temporary_member_roles" + `); + await queryRunner.query(` + CREATE TABLE "member_roles" ( + "index" integer NOT NULL, + "role_id" varchar NOT NULL, + PRIMARY KEY ("index", "role_id") + ) + `); + await queryRunner.query(` + INSERT INTO "member_roles"("index", "role_id") + SELECT "index", + "role_id" + FROM "temporary_member_roles" + `); + await queryRunner.query(` + DROP TABLE "temporary_member_roles" + `); + await queryRunner.query(` + CREATE INDEX "IDX_e9080e7a7997a0170026d5139c" ON "member_roles" ("role_id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_5d7ddc8a5f9c167f548625e772" ON "member_roles" ("index") + `); + await queryRunner.query(` + ALTER TABLE "notes" + RENAME TO "temporary_notes" + `); + await queryRunner.query(` + CREATE TABLE "notes" ( + "id" varchar PRIMARY KEY NOT NULL, + "content" varchar NOT NULL, + "owner_id" varchar, + "target_id" varchar, + CONSTRAINT "UQ_74e6689b9568cc965b8bfc9150b" UNIQUE ("owner_id", "target_id") + ) + `); + await queryRunner.query(` + INSERT INTO "notes"("id", "content", "owner_id", "target_id") + SELECT "id", + "content", + "owner_id", + "target_id" + FROM "temporary_notes" + `); + await queryRunner.query(` + DROP TABLE "temporary_notes" + `); + await queryRunner.query(` + ALTER TABLE "sticker_packs" + RENAME TO "temporary_sticker_packs" + `); + await queryRunner.query(` + CREATE TABLE "sticker_packs" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "banner_asset_id" varchar, + "cover_sticker_id" varchar, + "coverStickerId" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "sticker_packs"( + "id", + "name", + "description", + "banner_asset_id", + "cover_sticker_id", + "coverStickerId" + ) + SELECT "id", + "name", + "description", + "banner_asset_id", + "cover_sticker_id", + "coverStickerId" + FROM "temporary_sticker_packs" + `); + await queryRunner.query(` + DROP TABLE "temporary_sticker_packs" + `); + await queryRunner.query(` + ALTER TABLE "sessions" + RENAME TO "temporary_sessions" + `); + await queryRunner.query(` + CREATE TABLE "sessions" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "session_id" varchar NOT NULL, + "activities" text, + "client_info" text NOT NULL, + "status" varchar NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "sessions"( + "id", + "user_id", + "session_id", + "activities", + "client_info", + "status" + ) + SELECT "id", + "user_id", + "session_id", + "activities", + "client_info", + "status" + FROM "temporary_sessions" + `); + await queryRunner.query(` + DROP TABLE "temporary_sessions" + `); + await queryRunner.query(` + ALTER TABLE "audit_logs" + RENAME TO "temporary_audit_logs" + `); + await queryRunner.query(` + CREATE TABLE "audit_logs" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "action_type" integer NOT NULL, + "options" text, + "changes" text NOT NULL, + "reason" varchar, + "target_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "audit_logs"( + "id", + "user_id", + "action_type", + "options", + "changes", + "reason", + "target_id" + ) + SELECT "id", + "user_id", + "action_type", + "options", + "changes", + "reason", + "target_id" + FROM "temporary_audit_logs" + `); + await queryRunner.query(` + DROP TABLE "temporary_audit_logs" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "teams" + RENAME TO "temporary_teams" + `); + await queryRunner.query(` + CREATE TABLE "teams" ( + "id" varchar PRIMARY KEY NOT NULL, + "icon" varchar, + "name" varchar NOT NULL, + "owner_user_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "teams"("id", "icon", "name", "owner_user_id") + SELECT "id", + "icon", + "name", + "owner_user_id" + FROM "temporary_teams" + `); + await queryRunner.query(` + DROP TABLE "temporary_teams" + `); + await queryRunner.query(` + ALTER TABLE "team_members" + RENAME TO "temporary_team_members" + `); + await queryRunner.query(` + CREATE TABLE "team_members" ( + "id" varchar PRIMARY KEY NOT NULL, + "membership_state" integer NOT NULL, + "permissions" text NOT NULL, + "team_id" varchar, + "user_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "team_members"( + "id", + "membership_state", + "permissions", + "team_id", + "user_id" + ) + SELECT "id", + "membership_state", + "permissions", + "team_id", + "user_id" + FROM "temporary_team_members" + `); + await queryRunner.query(` + DROP TABLE "temporary_team_members" + `); + await queryRunner.query(` + ALTER TABLE "guilds" + RENAME TO "temporary_guilds" + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + FROM "temporary_guilds" + `); + await queryRunner.query(` + DROP TABLE "temporary_guilds" + `); + await queryRunner.query(` + ALTER TABLE "templates" + RENAME TO "temporary_templates" + `); + await queryRunner.query(` + CREATE TABLE "templates" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "usage_count" integer, + "creator_id" varchar, + "created_at" datetime NOT NULL, + "updated_at" datetime NOT NULL, + "source_guild_id" varchar, + "serialized_source_guild" text NOT NULL, + CONSTRAINT "UQ_be38737bf339baf63b1daeffb55" UNIQUE ("code") + ) + `); + await queryRunner.query(` + INSERT INTO "templates"( + "id", + "code", + "name", + "description", + "usage_count", + "creator_id", + "created_at", + "updated_at", + "source_guild_id", + "serialized_source_guild" + ) + SELECT "id", + "code", + "name", + "description", + "usage_count", + "creator_id", + "created_at", + "updated_at", + "source_guild_id", + "serialized_source_guild" + FROM "temporary_templates" + `); + await queryRunner.query(` + DROP TABLE "temporary_templates" + `); + await queryRunner.query(` + ALTER TABLE "emojis" + RENAME TO "temporary_emojis" + `); + await queryRunner.query(` + CREATE TABLE "emojis" ( + "id" varchar PRIMARY KEY NOT NULL, + "animated" boolean NOT NULL, + "available" boolean NOT NULL, + "guild_id" varchar NOT NULL, + "user_id" varchar, + "managed" boolean NOT NULL, + "name" varchar NOT NULL, + "require_colons" boolean NOT NULL, + "roles" text NOT NULL, + "groups" text + ) + `); + await queryRunner.query(` + INSERT INTO "emojis"( + "id", + "animated", + "available", + "guild_id", + "user_id", + "managed", + "name", + "require_colons", + "roles", + "groups" + ) + SELECT "id", + "animated", + "available", + "guild_id", + "user_id", + "managed", + "name", + "require_colons", + "roles", + "groups" + FROM "temporary_emojis" + `); + await queryRunner.query(` + DROP TABLE "temporary_emojis" + `); + await queryRunner.query(` + ALTER TABLE "channels" + RENAME TO "temporary_channels" + `); + await queryRunner.query(` + CREATE TABLE "channels" ( + "id" varchar PRIMARY KEY NOT NULL, + "created_at" datetime NOT NULL, + "name" varchar, + "icon" text, + "type" integer NOT NULL, + "last_message_id" varchar, + "guild_id" varchar, + "parent_id" varchar, + "owner_id" varchar, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" varchar, + "retention_policy_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "channels"( + "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + ) + SELECT "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + FROM "temporary_channels" + `); + await queryRunner.query(` + DROP TABLE "temporary_channels" + `); + await queryRunner.query(` + ALTER TABLE "voice_states" + RENAME TO "temporary_voice_states" + `); + await queryRunner.query(` + CREATE TABLE "voice_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "user_id" varchar, + "session_id" varchar NOT NULL, + "token" varchar, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "self_deaf" boolean NOT NULL, + "self_mute" boolean NOT NULL, + "self_stream" boolean, + "self_video" boolean NOT NULL, + "suppress" boolean NOT NULL, + "request_to_speak_timestamp" datetime + ) + `); + await queryRunner.query(` + INSERT INTO "voice_states"( + "id", + "guild_id", + "channel_id", + "user_id", + "session_id", + "token", + "deaf", + "mute", + "self_deaf", + "self_mute", + "self_stream", + "self_video", + "suppress", + "request_to_speak_timestamp" + ) + SELECT "id", + "guild_id", + "channel_id", + "user_id", + "session_id", + "token", + "deaf", + "mute", + "self_deaf", + "self_mute", + "self_stream", + "self_video", + "suppress", + "request_to_speak_timestamp" + FROM "temporary_voice_states" + `); + await queryRunner.query(` + DROP TABLE "temporary_voice_states" + `); + await queryRunner.query(` + ALTER TABLE "invites" + RENAME TO "temporary_invites" + `); + await queryRunner.query(` + CREATE TABLE "invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean + ) + `); + await queryRunner.query(` + INSERT INTO "invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "temporary_invites" + `); + await queryRunner.query(` + DROP TABLE "temporary_invites" + `); + await queryRunner.query(` + DROP INDEX "IDX_0abf8b443321bd3cf7f81ee17a" + `); + await queryRunner.query(` + ALTER TABLE "read_states" + RENAME TO "temporary_read_states" + `); + await queryRunner.query(` + CREATE TABLE "read_states" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "last_message_id" varchar, + "public_ack" varchar, + "notifications_cursor" varchar, + "last_pin_timestamp" datetime, + "mention_count" integer + ) + `); + await queryRunner.query(` + INSERT INTO "read_states"( + "id", + "channel_id", + "user_id", + "last_message_id", + "public_ack", + "notifications_cursor", + "last_pin_timestamp", + "mention_count" + ) + SELECT "id", + "channel_id", + "user_id", + "last_message_id", + "public_ack", + "notifications_cursor", + "last_pin_timestamp", + "mention_count" + FROM "temporary_read_states" + `); + await queryRunner.query(` + DROP TABLE "temporary_read_states" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_0abf8b443321bd3cf7f81ee17a" ON "read_states" ("channel_id", "user_id") + `); + await queryRunner.query(` + DROP INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" + `); + await queryRunner.query(` + DROP INDEX "IDX_05535bc695e9f7ee104616459d" + `); + await queryRunner.query(` + DROP INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" + `); + await queryRunner.query(` + ALTER TABLE "messages" + RENAME TO "temporary_messages" + `); + await queryRunner.query(` + CREATE TABLE "messages" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar, + "guild_id" varchar, + "author_id" varchar, + "member_id" varchar, + "webhook_id" varchar, + "application_id" varchar, + "content" varchar, + "timestamp" datetime NOT NULL DEFAULT (datetime('now')), + "edited_timestamp" datetime, + "tts" boolean, + "mention_everyone" boolean, + "embeds" text NOT NULL, + "reactions" text NOT NULL, + "nonce" text, + "pinned" boolean, + "type" integer NOT NULL, + "activity" text, + "flags" varchar, + "message_reference" text, + "interaction" text, + "components" text, + "message_reference_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "messages"( + "id", + "channel_id", + "guild_id", + "author_id", + "member_id", + "webhook_id", + "application_id", + "content", + "timestamp", + "edited_timestamp", + "tts", + "mention_everyone", + "embeds", + "reactions", + "nonce", + "pinned", + "type", + "activity", + "flags", + "message_reference", + "interaction", + "components", + "message_reference_id" + ) + SELECT "id", + "channel_id", + "guild_id", + "author_id", + "member_id", + "webhook_id", + "application_id", + "content", + "timestamp", + "edited_timestamp", + "tts", + "mention_everyone", + "embeds", + "reactions", + "nonce", + "pinned", + "type", + "activity", + "flags", + "message_reference", + "interaction", + "components", + "message_reference_id" + FROM "temporary_messages" + `); + await queryRunner.query(` + DROP TABLE "temporary_messages" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" ON "messages" ("channel_id", "id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_05535bc695e9f7ee104616459d" ON "messages" ("author_id") + `); + await queryRunner.query(` + CREATE INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" ON "messages" ("channel_id") + `); + await queryRunner.query(` + ALTER TABLE "attachments" + RENAME TO "temporary_attachments" + `); + await queryRunner.query(` + CREATE TABLE "attachments" ( + "id" varchar PRIMARY KEY NOT NULL, + "filename" varchar NOT NULL, + "size" integer NOT NULL, + "url" varchar NOT NULL, + "proxy_url" varchar NOT NULL, + "height" integer, + "width" integer, + "content_type" varchar, + "message_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "attachments"( + "id", + "filename", + "size", + "url", + "proxy_url", + "height", + "width", + "content_type", + "message_id" + ) + SELECT "id", + "filename", + "size", + "url", + "proxy_url", + "height", + "width", + "content_type", + "message_id" + FROM "temporary_attachments" + `); + await queryRunner.query(` + DROP TABLE "temporary_attachments" + `); + await queryRunner.query(` + ALTER TABLE "stickers" + RENAME TO "temporary_stickers" + `); + await queryRunner.query(` + CREATE TABLE "stickers" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "description" varchar, + "available" boolean, + "tags" varchar, + "pack_id" varchar, + "guild_id" varchar, + "user_id" varchar, + "type" integer NOT NULL, + "format_type" integer NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "stickers"( + "id", + "name", + "description", + "available", + "tags", + "pack_id", + "guild_id", + "user_id", + "type", + "format_type" + ) + SELECT "id", + "name", + "description", + "available", + "tags", + "pack_id", + "guild_id", + "user_id", + "type", + "format_type" + FROM "temporary_stickers" + `); + await queryRunner.query(` + DROP TABLE "temporary_stickers" + `); + await queryRunner.query(` + ALTER TABLE "webhooks" + RENAME TO "temporary_webhooks" + `); + await queryRunner.query(` + CREATE TABLE "webhooks" ( + "id" varchar PRIMARY KEY NOT NULL, + "type" integer NOT NULL, + "name" varchar, + "avatar" varchar, + "token" varchar, + "guild_id" varchar, + "channel_id" varchar, + "application_id" varchar, + "user_id" varchar, + "source_guild_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "webhooks"( + "id", + "type", + "name", + "avatar", + "token", + "guild_id", + "channel_id", + "application_id", + "user_id", + "source_guild_id" + ) + SELECT "id", + "type", + "name", + "avatar", + "token", + "guild_id", + "channel_id", + "application_id", + "user_id", + "source_guild_id" + FROM "temporary_webhooks" + `); + await queryRunner.query(` + DROP TABLE "temporary_webhooks" + `); + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + ALTER TABLE "members" + RENAME TO "temporary_members" + `); + await queryRunner.query(` + CREATE TABLE "members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "temporary_members" + `); + await queryRunner.query(` + DROP TABLE "temporary_members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + ALTER TABLE "roles" + RENAME TO "temporary_roles" + `); + await queryRunner.query(` + CREATE TABLE "roles" ( + "id" varchar PRIMARY KEY NOT NULL, + "guild_id" varchar, + "color" integer NOT NULL, + "hoist" boolean NOT NULL, + "managed" boolean NOT NULL, + "mentionable" boolean NOT NULL, + "name" varchar NOT NULL, + "permissions" varchar NOT NULL, + "position" integer NOT NULL, + "icon" varchar, + "unicode_emoji" varchar, + "tags" text + ) + `); + await queryRunner.query(` + INSERT INTO "roles"( + "id", + "guild_id", + "color", + "hoist", + "managed", + "mentionable", + "name", + "permissions", + "position", + "icon", + "unicode_emoji", + "tags" + ) + SELECT "id", + "guild_id", + "color", + "hoist", + "managed", + "mentionable", + "name", + "permissions", + "position", + "icon", + "unicode_emoji", + "tags" + FROM "temporary_roles" + `); + await queryRunner.query(` + DROP TABLE "temporary_roles" + `); + await queryRunner.query(` + ALTER TABLE "recipients" + RENAME TO "temporary_recipients" + `); + await queryRunner.query(` + CREATE TABLE "recipients" ( + "id" varchar PRIMARY KEY NOT NULL, + "channel_id" varchar NOT NULL, + "user_id" varchar NOT NULL, + "closed" boolean NOT NULL DEFAULT (0) + ) + `); + await queryRunner.query(` + INSERT INTO "recipients"("id", "channel_id", "user_id", "closed") + SELECT "id", + "channel_id", + "user_id", + "closed" + FROM "temporary_recipients" + `); + await queryRunner.query(` + DROP TABLE "temporary_recipients" + `); + await queryRunner.query(` + ALTER TABLE "bans" + RENAME TO "temporary_bans" + `); + await queryRunner.query(` + CREATE TABLE "bans" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "guild_id" varchar, + "executor_id" varchar, + "ip" varchar NOT NULL, + "reason" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "bans"( + "id", + "user_id", + "guild_id", + "executor_id", + "ip", + "reason" + ) + SELECT "id", + "user_id", + "guild_id", + "executor_id", + "ip", + "reason" + FROM "temporary_bans" + `); + await queryRunner.query(` + DROP TABLE "temporary_bans" + `); + await queryRunner.query(` + ALTER TABLE "backup_codes" + RENAME TO "temporary_backup_codes" + `); + await queryRunner.query(` + CREATE TABLE "backup_codes" ( + "id" varchar PRIMARY KEY NOT NULL, + "code" varchar NOT NULL, + "consumed" boolean NOT NULL, + "expired" boolean NOT NULL, + "user_id" varchar + ) + `); + await queryRunner.query(` + INSERT INTO "backup_codes"("id", "code", "consumed", "expired", "user_id") + SELECT "id", + "code", + "consumed", + "expired", + "user_id" + FROM "temporary_backup_codes" + `); + await queryRunner.query(` + DROP TABLE "temporary_backup_codes" + `); + await queryRunner.query(` + ALTER TABLE "connected_accounts" + RENAME TO "temporary_connected_accounts" + `); + await queryRunner.query(` + CREATE TABLE "connected_accounts" ( + "id" varchar PRIMARY KEY NOT NULL, + "user_id" varchar, + "access_token" varchar NOT NULL, + "friend_sync" boolean NOT NULL, + "name" varchar NOT NULL, + "revoked" boolean NOT NULL, + "show_activity" boolean NOT NULL, + "type" varchar NOT NULL, + "verified" boolean NOT NULL, + "visibility" integer NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "connected_accounts"( + "id", + "user_id", + "access_token", + "friend_sync", + "name", + "revoked", + "show_activity", + "type", + "verified", + "visibility" + ) + SELECT "id", + "user_id", + "access_token", + "friend_sync", + "name", + "revoked", + "show_activity", + "type", + "verified", + "visibility" + FROM "temporary_connected_accounts" + `); + await queryRunner.query(` + DROP TABLE "temporary_connected_accounts" + `); + await queryRunner.query(` + DROP INDEX "IDX_a0b2ff0a598df0b0d055934a17" + `); + await queryRunner.query(` + ALTER TABLE "relationships" + RENAME TO "temporary_relationships" + `); + await queryRunner.query(` + CREATE TABLE "relationships" ( + "id" varchar PRIMARY KEY NOT NULL, + "from_id" varchar NOT NULL, + "to_id" varchar NOT NULL, + "nickname" varchar, + "type" integer NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "relationships"("id", "from_id", "to_id", "nickname", "type") + SELECT "id", + "from_id", + "to_id", + "nickname", + "type" + FROM "temporary_relationships" + `); + await queryRunner.query(` + DROP TABLE "temporary_relationships" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_a0b2ff0a598df0b0d055934a17" ON "relationships" ("from_id", "to_id") + `); + await queryRunner.query(` + DROP INDEX "IDX_e22a70819d07659c7a71c112a1" + `); + await queryRunner.query(` + DROP INDEX "IDX_40bb6f23e7cc133292e92829d2" + `); + await queryRunner.query(` + DROP TABLE "message_stickers" + `); + await queryRunner.query(` + DROP INDEX "IDX_bdb8c09e1464cabf62105bf4b9" + `); + await queryRunner.query(` + DROP INDEX "IDX_2a27102ecd1d81b4582a436092" + `); + await queryRunner.query(` + DROP TABLE "message_channel_mentions" + `); + await queryRunner.query(` + DROP INDEX "IDX_29d63eb1a458200851bc37d074" + `); + await queryRunner.query(` + DROP INDEX "IDX_a8242cf535337a490b0feaea0b" + `); + await queryRunner.query(` + DROP TABLE "message_role_mentions" + `); + await queryRunner.query(` + DROP INDEX "IDX_b831eb18ceebd28976239b1e2f" + `); + await queryRunner.query(` + DROP INDEX "IDX_a343387fc560ef378760681c23" + `); + await queryRunner.query(` + DROP TABLE "message_user_mentions" + `); + await queryRunner.query(` + DROP INDEX "IDX_e9080e7a7997a0170026d5139c" + `); + await queryRunner.query(` + DROP INDEX "IDX_5d7ddc8a5f9c167f548625e772" + `); + await queryRunner.query(` + DROP TABLE "member_roles" + `); + await queryRunner.query(` + DROP TABLE "notes" + `); + await queryRunner.query(` + DROP TABLE "client_release" + `); + await queryRunner.query(` + DROP TABLE "sticker_packs" + `); + await queryRunner.query(` + DROP TABLE "sessions" + `); + await queryRunner.query(` + DROP TABLE "rate_limits" + `); + await queryRunner.query(` + DROP TABLE "categories" + `); + await queryRunner.query(` + DROP TABLE "audit_logs" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + DROP TABLE "teams" + `); + await queryRunner.query(` + DROP TABLE "team_members" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + DROP TABLE "templates" + `); + await queryRunner.query(` + DROP TABLE "emojis" + `); + await queryRunner.query(` + DROP TABLE "channels" + `); + await queryRunner.query(` + DROP TABLE "voice_states" + `); + await queryRunner.query(` + DROP TABLE "invites" + `); + await queryRunner.query(` + DROP INDEX "IDX_0abf8b443321bd3cf7f81ee17a" + `); + await queryRunner.query(` + DROP TABLE "read_states" + `); + await queryRunner.query(` + DROP INDEX "IDX_3ed7a60fb7dbe04e1ba9332a8b" + `); + await queryRunner.query(` + DROP INDEX "IDX_05535bc695e9f7ee104616459d" + `); + await queryRunner.query(` + DROP INDEX "IDX_86b9109b155eb70c0a2ca3b4b6" + `); + await queryRunner.query(` + DROP TABLE "messages" + `); + await queryRunner.query(` + DROP TABLE "attachments" + `); + await queryRunner.query(` + DROP TABLE "stickers" + `); + await queryRunner.query(` + DROP TABLE "webhooks" + `); + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + DROP TABLE "members" + `); + await queryRunner.query(` + DROP TABLE "roles" + `); + await queryRunner.query(` + DROP TABLE "recipients" + `); + await queryRunner.query(` + DROP TABLE "bans" + `); + await queryRunner.query(` + DROP TABLE "backup_codes" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + DROP TABLE "connected_accounts" + `); + await queryRunner.query(` + DROP INDEX "IDX_a0b2ff0a598df0b0d055934a17" + `); + await queryRunner.query(` + DROP TABLE "relationships" + `); + await queryRunner.query(` + DROP TABLE "config" + `); + } +} diff --git a/src/util/migrations/sqlite/1659921722863-premium_since_as_date.ts b/src/util/migrations/sqlite/1659921722863-premium_since_as_date.ts new file mode 100644
index 00000000..b6307ee9 --- /dev/null +++ b/src/util/migrations/sqlite/1659921722863-premium_since_as_date.ts
@@ -0,0 +1,251 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class premiumSinceAsDate1659921722863 implements MigrationInterface { + name = "premiumSinceAsDate1659921722863"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + CREATE TABLE "temporary_members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar, + CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "members" + `); + await queryRunner.query(` + DROP TABLE "members" + `); + await queryRunner.query(` + ALTER TABLE "temporary_members" + RENAME TO "members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + CREATE TABLE "temporary_members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" datetime, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar, + CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "members" + `); + await queryRunner.query(` + DROP TABLE "members" + `); + await queryRunner.query(` + ALTER TABLE "temporary_members" + RENAME TO "members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + ALTER TABLE "members" + RENAME TO "temporary_members" + `); + await queryRunner.query(` + CREATE TABLE "members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar, + CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "temporary_members" + `); + await queryRunner.query(` + DROP TABLE "temporary_members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + await queryRunner.query(` + DROP INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" + `); + await queryRunner.query(` + ALTER TABLE "members" + RENAME TO "temporary_members" + `); + await queryRunner.query(` + CREATE TABLE "members" ( + "index" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "id" varchar NOT NULL, + "guild_id" varchar NOT NULL, + "nick" varchar, + "joined_at" datetime NOT NULL, + "premium_since" bigint, + "deaf" boolean NOT NULL, + "mute" boolean NOT NULL, + "pending" boolean NOT NULL, + "settings" text NOT NULL, + "last_message_id" varchar, + "joined_by" varchar, + CONSTRAINT "FK_16aceddd5b89825b8ed6029ad1c" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_28b53062261b996d9c99fa12404" FOREIGN KEY ("id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "members"( + "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + ) + SELECT "index", + "id", + "guild_id", + "nick", + "joined_at", + "premium_since", + "deaf", + "mute", + "pending", + "settings", + "last_message_id", + "joined_by" + FROM "temporary_members" + `); + await queryRunner.query(` + DROP TABLE "temporary_members" + `); + await queryRunner.query(` + CREATE UNIQUE INDEX "IDX_bb2bf9386ac443afbbbf9f12d3" ON "members" ("id", "guild_id") + `); + } +} diff --git a/src/util/migrations/sqlite/1660130536131-updated-applications.ts b/src/util/migrations/sqlite/1660130536131-updated-applications.ts new file mode 100644
index 00000000..bcb1c929 --- /dev/null +++ b/src/util/migrations/sqlite/1660130536131-updated-applications.ts
@@ -0,0 +1,828 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class updatedApplications1660130536131 implements MigrationInterface { + name = "updatedApplications1660130536131"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_2ce5a55796fe4c2f77ece57a647" FOREIGN KEY ("bot_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + } +} diff --git a/src/util/migrations/sqlite/1660257576211-CodeCleanup1.ts b/src/util/migrations/sqlite/1660257576211-CodeCleanup1.ts new file mode 100644
index 00000000..95410544 --- /dev/null +++ b/src/util/migrations/sqlite/1660257576211-CodeCleanup1.ts
@@ -0,0 +1,325 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup11660257576211 implements MigrationInterface { + name = "CodeCleanup11660257576211"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "user_settings" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_timeout" integer, + "allow_accessibility_detection" boolean, + "animate_emoji" boolean, + "animate_stickers" integer, + "contact_sync_enabled" boolean, + "convert_emoticons" boolean, + "custom_status" text, + "default_guilds_restricted" boolean, + "detect_platform_accounts" boolean, + "developer_mode" boolean, + "disable_games_tab" boolean, + "enable_tts_command" boolean, + "explicit_content_filter" integer, + "friend_source_flags" text, + "gateway_connected" boolean, + "gif_auto_play" boolean, + "guild_folders" text, + "guild_positions" text, + "inline_attachment_media" boolean, + "inline_embed_media" boolean, + "locale" varchar, + "message_display_compact" boolean, + "native_phone_integration_enabled" boolean, + "render_embeds" boolean, + "render_reactions" boolean, + "restricted_guilds" text, + "show_current_game" boolean, + "status" varchar, + "stream_notifications_enabled" boolean, + "theme" varchar, + "timezone_offset" integer + ) + `); + await queryRunner.query(` + CREATE TABLE "temporary_guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + "premium_progress_bar_enabled" boolean NOT NULL, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + FROM "guilds" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + ALTER TABLE "temporary_guilds" + RENAME TO "guilds" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "guilds" + RENAME TO "temporary_guilds" + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent" + FROM "temporary_guilds" + `); + await queryRunner.query(` + DROP TABLE "temporary_guilds" + `); + await queryRunner.query(` + DROP TABLE "user_settings" + `); + } +} diff --git a/src/util/migrations/sqlite/1660257795259-CodeCleanup2.ts b/src/util/migrations/sqlite/1660257795259-CodeCleanup2.ts new file mode 100644
index 00000000..b21e190c --- /dev/null +++ b/src/util/migrations/sqlite/1660257795259-CodeCleanup2.ts
@@ -0,0 +1,571 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup21660257795259 implements MigrationInterface { + name = "CodeCleanup21660257795259"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + "premium_progress_bar_enabled" boolean NOT NULL, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + FROM "guilds" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + ALTER TABLE "temporary_guilds" + RENAME TO "guilds" + `); + await queryRunner.query(` + CREATE TABLE "temporary_guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + "premium_progress_bar_enabled" boolean, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + FROM "guilds" + `); + await queryRunner.query(` + DROP TABLE "guilds" + `); + await queryRunner.query(` + ALTER TABLE "temporary_guilds" + RENAME TO "guilds" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "guilds" + RENAME TO "temporary_guilds" + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + "premium_progress_bar_enabled" boolean NOT NULL, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + FROM "temporary_guilds" + `); + await queryRunner.query(` + DROP TABLE "temporary_guilds" + `); + await queryRunner.query(` + ALTER TABLE "guilds" + RENAME TO "temporary_guilds" + `); + await queryRunner.query(` + CREATE TABLE "guilds" ( + "id" varchar PRIMARY KEY NOT NULL, + "afk_channel_id" varchar, + "afk_timeout" integer, + "banner" varchar, + "default_message_notifications" integer, + "description" varchar, + "discovery_splash" varchar, + "explicit_content_filter" integer, + "features" text NOT NULL, + "primary_category_id" integer, + "icon" varchar, + "large" boolean, + "max_members" integer, + "max_presences" integer, + "max_video_channel_users" integer, + "member_count" integer, + "presence_count" integer, + "template_id" varchar, + "mfa_level" integer, + "name" varchar NOT NULL, + "owner_id" varchar, + "preferred_locale" varchar, + "premium_subscription_count" integer, + "premium_tier" integer, + "public_updates_channel_id" varchar, + "rules_channel_id" varchar, + "region" varchar, + "splash" varchar, + "system_channel_id" varchar, + "system_channel_flags" integer, + "unavailable" boolean, + "verification_level" integer, + "welcome_screen" text NOT NULL, + "widget_channel_id" varchar, + "widget_enabled" boolean, + "nsfw_level" integer, + "nsfw" boolean, + "parent" varchar, + "premium_progress_bar_enabled" boolean NOT NULL, + CONSTRAINT "FK_f591a66b8019d87b0fe6c12dad6" FOREIGN KEY ("afk_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_e2a2f873a64a5cf62526de42325" FOREIGN KEY ("template_id") REFERENCES "templates" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_fc1a451727e3643ca572a3bb394" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_8d450b016dc8bec35f36729e4b0" FOREIGN KEY ("public_updates_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_95828668aa333460582e0ca6396" FOREIGN KEY ("rules_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_cfc3d3ad260f8121c95b31a1fce" FOREIGN KEY ("system_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_9d1d665379eefde7876a17afa99" FOREIGN KEY ("widget_channel_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "guilds"( + "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + ) + SELECT "id", + "afk_channel_id", + "afk_timeout", + "banner", + "default_message_notifications", + "description", + "discovery_splash", + "explicit_content_filter", + "features", + "primary_category_id", + "icon", + "large", + "max_members", + "max_presences", + "max_video_channel_users", + "member_count", + "presence_count", + "template_id", + "mfa_level", + "name", + "owner_id", + "preferred_locale", + "premium_subscription_count", + "premium_tier", + "public_updates_channel_id", + "rules_channel_id", + "region", + "splash", + "system_channel_id", + "system_channel_flags", + "unavailable", + "verification_level", + "welcome_screen", + "widget_channel_id", + "widget_enabled", + "nsfw_level", + "nsfw", + "parent", + "premium_progress_bar_enabled" + FROM "temporary_guilds" + `); + await queryRunner.query(` + DROP TABLE "temporary_guilds" + `); + } +} diff --git a/src/util/migrations/sqlite/1660258351379-CodeCleanup3.ts b/src/util/migrations/sqlite/1660258351379-CodeCleanup3.ts new file mode 100644
index 00000000..b19864fa --- /dev/null +++ b/src/util/migrations/sqlite/1660258351379-CodeCleanup3.ts
@@ -0,0 +1,230 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup31660258351379 implements MigrationInterface { + name = "CodeCleanup31660258351379"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + FROM "users" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + ALTER TABLE "temporary_users" + RENAME TO "users" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + RENAME TO "temporary_users" + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "settings" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + FROM "temporary_users" + `); + await queryRunner.query(` + DROP TABLE "temporary_users" + `); + } +} diff --git a/src/util/migrations/sqlite/1660260672914-CodeCleanup4.ts b/src/util/migrations/sqlite/1660260672914-CodeCleanup4.ts new file mode 100644
index 00000000..ed284bc8 --- /dev/null +++ b/src/util/migrations/sqlite/1660260672914-CodeCleanup4.ts
@@ -0,0 +1,458 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CodeCleanup41660260672914 implements MigrationInterface { + name = "CodeCleanup41660260672914"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + "settingsId" varchar, + CONSTRAINT "UQ_b1dd13b6ed980004a795ca184a6" UNIQUE ("settingsId") + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + FROM "users" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + ALTER TABLE "temporary_users" + RENAME TO "users" + `); + await queryRunner.query(` + CREATE TABLE "temporary_users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + "settingsId" varchar, + CONSTRAINT "UQ_b1dd13b6ed980004a795ca184a6" UNIQUE ("settingsId"), + CONSTRAINT "FK_76ba283779c8441fd5ff819c8cf" FOREIGN KEY ("settingsId") REFERENCES "user_settings" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + FROM "users" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + ALTER TABLE "temporary_users" + RENAME TO "users" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + RENAME TO "temporary_users" + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + "settingsId" varchar, + CONSTRAINT "UQ_b1dd13b6ed980004a795ca184a6" UNIQUE ("settingsId") + ) + `); + await queryRunner.query(` + INSERT INTO "users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + FROM "temporary_users" + `); + await queryRunner.query(` + DROP TABLE "temporary_users" + `); + await queryRunner.query(` + ALTER TABLE "users" + RENAME TO "temporary_users" + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL + ) + `); + await queryRunner.query(` + INSERT INTO "users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes" + FROM "temporary_users" + `); + await queryRunner.query(` + DROP TABLE "temporary_users" + `); + } +} diff --git a/src/util/migrations/sqlite/1660416010862-InvitersAreDeletable.ts b/src/util/migrations/sqlite/1660416010862-InvitersAreDeletable.ts new file mode 100644
index 00000000..a05082c6 --- /dev/null +++ b/src/util/migrations/sqlite/1660416010862-InvitersAreDeletable.ts
@@ -0,0 +1,245 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class InvitersAreDeletable1660416010862 implements MigrationInterface { + name = "InvitersAreDeletable1660416010862"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "invites" + `); + await queryRunner.query(` + DROP TABLE "invites" + `); + await queryRunner.query(` + ALTER TABLE "temporary_invites" + RENAME TO "invites" + `); + await queryRunner.query(` + CREATE TABLE "temporary_invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "invites" + `); + await queryRunner.query(` + DROP TABLE "invites" + `); + await queryRunner.query(` + ALTER TABLE "temporary_invites" + RENAME TO "invites" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "invites" + RENAME TO "temporary_invites" + `); + await queryRunner.query(` + CREATE TABLE "invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "temporary_invites" + `); + await queryRunner.query(` + DROP TABLE "temporary_invites" + `); + await queryRunner.query(` + ALTER TABLE "invites" + RENAME TO "temporary_invites" + `); + await queryRunner.query(` + CREATE TABLE "invites" ( + "code" varchar PRIMARY KEY NOT NULL, + "temporary" boolean NOT NULL, + "uses" integer NOT NULL, + "max_uses" integer NOT NULL, + "max_age" integer NOT NULL, + "created_at" datetime NOT NULL, + "expires_at" datetime NOT NULL, + "guild_id" varchar, + "channel_id" varchar, + "inviter_id" varchar, + "target_user_id" varchar, + "target_user_type" integer, + "vanity_url" boolean, + CONSTRAINT "FK_11a0d394f8fc649c19ce5f16b59" FOREIGN KEY ("target_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_15c35422032e0b22b4ada95f48f" FOREIGN KEY ("inviter_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_6a15b051fe5050aa00a4b9ff0f6" FOREIGN KEY ("channel_id") REFERENCES "channels" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_3f4939aa1461e8af57fea3fb05d" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "invites"( + "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + ) + SELECT "code", + "temporary", + "uses", + "max_uses", + "max_age", + "created_at", + "expires_at", + "guild_id", + "channel_id", + "inviter_id", + "target_user_id", + "target_user_type", + "vanity_url" + FROM "temporary_invites" + `); + await queryRunner.query(` + DROP TABLE "temporary_invites" + `); + } +} diff --git a/src/util/migrations/sqlite/1660538628956-sync_migrations.ts b/src/util/migrations/sqlite/1660538628956-sync_migrations.ts new file mode 100644
index 00000000..95c59d28 --- /dev/null +++ b/src/util/migrations/sqlite/1660538628956-sync_migrations.ts
@@ -0,0 +1,171 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class syncMigrations1660538628956 implements MigrationInterface { + name = "syncMigrations1660538628956"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_channels" ( + "id" varchar PRIMARY KEY NOT NULL, + "created_at" datetime NOT NULL, + "name" varchar, + "icon" text, + "type" integer NOT NULL, + "last_message_id" varchar, + "guild_id" varchar, + "parent_id" varchar, + "owner_id" varchar, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" varchar, + "retention_policy_id" varchar, + "flags" integer, + "default_thread_rate_limit_per_user" integer, + CONSTRAINT "FK_3873ed438575cce703ecff4fc7b" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_3274522d14af40540b1a883fc80" FOREIGN KEY ("parent_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_c253dafe5f3a03ec00cd8fb4581" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_channels"( + "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + ) + SELECT "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + FROM "channels" + `); + await queryRunner.query(` + DROP TABLE "channels" + `); + await queryRunner.query(` + ALTER TABLE "temporary_channels" + RENAME TO "channels" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "channels" + RENAME TO "temporary_channels" + `); + await queryRunner.query(` + CREATE TABLE "channels" ( + "id" varchar PRIMARY KEY NOT NULL, + "created_at" datetime NOT NULL, + "name" varchar, + "icon" text, + "type" integer NOT NULL, + "last_message_id" varchar, + "guild_id" varchar, + "parent_id" varchar, + "owner_id" varchar, + "last_pin_timestamp" integer, + "default_auto_archive_duration" integer, + "position" integer, + "permission_overwrites" text, + "video_quality_mode" integer, + "bitrate" integer, + "user_limit" integer, + "nsfw" boolean, + "rate_limit_per_user" integer, + "topic" varchar, + "retention_policy_id" varchar, + CONSTRAINT "FK_3873ed438575cce703ecff4fc7b" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_3274522d14af40540b1a883fc80" FOREIGN KEY ("parent_id") REFERENCES "channels" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_c253dafe5f3a03ec00cd8fb4581" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE CASCADE ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "channels"( + "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + ) + SELECT "id", + "created_at", + "name", + "icon", + "type", + "last_message_id", + "guild_id", + "parent_id", + "owner_id", + "last_pin_timestamp", + "default_auto_archive_duration", + "position", + "permission_overwrites", + "video_quality_mode", + "bitrate", + "user_limit", + "nsfw", + "rate_limit_per_user", + "topic", + "retention_policy_id" + FROM "temporary_channels" + `); + await queryRunner.query(` + DROP TABLE "temporary_channels" + `); + } +} diff --git a/src/util/migrations/sqlite/1660549233583-fix_nullables.ts b/src/util/migrations/sqlite/1660549233583-fix_nullables.ts new file mode 100644
index 00000000..fa60bdc1 --- /dev/null +++ b/src/util/migrations/sqlite/1660549233583-fix_nullables.ts
@@ -0,0 +1,239 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class fixNullables1660549233583 implements MigrationInterface { + name = "fixNullables1660549233583"; + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + "settingsId" varchar, + CONSTRAINT "UQ_b1dd13b6ed980004a795ca184a6" UNIQUE ("settingsId"), + CONSTRAINT "FK_76ba283779c8441fd5ff819c8cf" FOREIGN KEY ("settingsId") REFERENCES "user_settings" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + FROM "users" + `); + await queryRunner.query(` + DROP TABLE "users" + `); + await queryRunner.query(` + ALTER TABLE "temporary_users" + RENAME TO "users" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "users" + RENAME TO "temporary_users" + `); + await queryRunner.query(` + CREATE TABLE "users" ( + "id" varchar PRIMARY KEY NOT NULL, + "username" varchar NOT NULL, + "discriminator" varchar NOT NULL, + "avatar" varchar, + "accent_color" integer, + "banner" varchar, + "phone" varchar, + "desktop" boolean NOT NULL, + "mobile" boolean NOT NULL, + "premium" boolean NOT NULL, + "premium_type" integer NOT NULL, + "bot" boolean NOT NULL, + "bio" varchar NOT NULL, + "system" boolean NOT NULL, + "nsfw_allowed" boolean NOT NULL, + "mfa_enabled" boolean NOT NULL, + "totp_secret" varchar, + "totp_last_ticket" varchar, + "created_at" datetime NOT NULL, + "premium_since" datetime, + "verified" boolean NOT NULL, + "disabled" boolean NOT NULL, + "deleted" boolean NOT NULL, + "email" varchar, + "flags" varchar NOT NULL, + "public_flags" integer NOT NULL, + "rights" bigint NOT NULL, + "data" text NOT NULL, + "fingerprints" text NOT NULL, + "extended_settings" text NOT NULL, + "notes" text NOT NULL, + "settingsId" varchar, + CONSTRAINT "UQ_b1dd13b6ed980004a795ca184a6" UNIQUE ("settingsId"), + CONSTRAINT "FK_76ba283779c8441fd5ff819c8cf" FOREIGN KEY ("settingsId") REFERENCES "user_settings" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "users"( + "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + ) + SELECT "id", + "username", + "discriminator", + "avatar", + "accent_color", + "banner", + "phone", + "desktop", + "mobile", + "premium", + "premium_type", + "bot", + "bio", + "system", + "nsfw_allowed", + "mfa_enabled", + "totp_secret", + "totp_last_ticket", + "created_at", + "premium_since", + "verified", + "disabled", + "deleted", + "email", + "flags", + "public_flags", + "rights", + "data", + "fingerprints", + "extended_settings", + "notes", + "settingsId" + FROM "temporary_users" + `); + await queryRunner.query(` + DROP TABLE "temporary_users" + `); + } +} diff --git a/gateway/src/schema/Activity.ts b/src/util/schemas/ActivitySchema.ts
index e18f66c8..d94557ea 100644 --- a/gateway/src/schema/Activity.ts +++ b/src/util/schemas/ActivitySchema.ts
@@ -11,7 +11,7 @@ export const ActivitySchema = { $created_at: Date, $timestamps: { $start: Number, - $end: Number, + $end: Number }, $application_id: String, $details: String, @@ -19,28 +19,28 @@ export const ActivitySchema = { $emoji: { $name: String, $id: String, - $animated: Boolean, + $animated: Boolean }, $party: { $id: String, - $size: [Number, Number], + $size: [Number, Number] }, $assets: { $large_image: String, $large_text: String, $small_image: String, - $small_text: String, + $small_text: String }, $secrets: { $join: String, $spectate: String, - $match: String, + $match: String }, $instance: Boolean, - $flags: String, - }, + $flags: String + } ], - $since: Number, // unix time (in milliseconds) of when the client went idle, or null if the client is not idle + $since: Number // unix time (in milliseconds) of when the client went idle, or null if the client is not idle }; export interface ActivitySchema { diff --git a/src/util/schemas/BanCreateSchema.ts b/src/util/schemas/BanCreateSchema.ts new file mode 100644
index 00000000..834577dc --- /dev/null +++ b/src/util/schemas/BanCreateSchema.ts
@@ -0,0 +1,4 @@ +export interface BanCreateSchema { + delete_message_days?: string; + reason?: string; +} diff --git a/src/util/schemas/BanModeratorSchema.ts b/src/util/schemas/BanModeratorSchema.ts new file mode 100644
index 00000000..afb76433 --- /dev/null +++ b/src/util/schemas/BanModeratorSchema.ts
@@ -0,0 +1,7 @@ +export interface BanModeratorSchema { + id: string; + user_id: string; + guild_id: string; + executor_id: string; + reason?: string | undefined; +} diff --git a/src/util/schemas/BanRegistrySchema.ts b/src/util/schemas/BanRegistrySchema.ts new file mode 100644
index 00000000..501f94dc --- /dev/null +++ b/src/util/schemas/BanRegistrySchema.ts
@@ -0,0 +1,8 @@ +export interface BanRegistrySchema { + id: string; + user_id: string; + guild_id: string; + executor_id: string; + ip?: string; + reason?: string | undefined; +} diff --git a/src/util/schemas/BulkDeleteSchema.ts b/src/util/schemas/BulkDeleteSchema.ts new file mode 100644
index 00000000..bfc4df65 --- /dev/null +++ b/src/util/schemas/BulkDeleteSchema.ts
@@ -0,0 +1,3 @@ +export interface BulkDeleteSchema { + messages: string[]; +} diff --git a/src/util/schemas/ChannelModifySchema.ts b/src/util/schemas/ChannelModifySchema.ts new file mode 100644
index 00000000..f5babef0 --- /dev/null +++ b/src/util/schemas/ChannelModifySchema.ts
@@ -0,0 +1,28 @@ +import { ChannelPermissionOverwriteType, ChannelType } from ".."; + +export interface ChannelModifySchema { + /** + * @maxLength 100 + */ + name?: string; + type?: ChannelType; + topic?: string; + icon?: string | null; + bitrate?: number; + user_limit?: number; + rate_limit_per_user?: number; + position?: number; + permission_overwrites?: { + id: string; + type: ChannelPermissionOverwriteType; + allow: string; + deny: string; + }[]; + parent_id?: string; + id?: string; // is not used (only for guild create) + nsfw?: boolean; + rtc_region?: string; + default_auto_archive_duration?: number; + flags?: number; + default_thread_rate_limit_per_user?: number; +} diff --git a/src/util/schemas/ChannelPermissionOverwriteSchema.ts b/src/util/schemas/ChannelPermissionOverwriteSchema.ts new file mode 100644
index 00000000..e8bc13bb --- /dev/null +++ b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
@@ -0,0 +1,5 @@ +import { ChannelPermissionOverwrite } from "@fosscord/util"; + +// TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel) + +export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite {} diff --git a/src/util/schemas/ChannelReorderSchema.ts b/src/util/schemas/ChannelReorderSchema.ts new file mode 100644
index 00000000..95c2eba9 --- /dev/null +++ b/src/util/schemas/ChannelReorderSchema.ts
@@ -0,0 +1 @@ +export type ChannelReorderSchema = { id: string; position?: number; lock_permissions?: boolean; parent_id?: string }[]; diff --git a/src/util/schemas/DmChannelCreateSchema.ts b/src/util/schemas/DmChannelCreateSchema.ts new file mode 100644
index 00000000..1b0fe86d --- /dev/null +++ b/src/util/schemas/DmChannelCreateSchema.ts
@@ -0,0 +1,4 @@ +export interface DmChannelCreateSchema { + name?: string; + recipients: string[]; +} diff --git a/src/util/schemas/EmojiCreateSchema.ts b/src/util/schemas/EmojiCreateSchema.ts new file mode 100644
index 00000000..34084713 --- /dev/null +++ b/src/util/schemas/EmojiCreateSchema.ts
@@ -0,0 +1,6 @@ +export interface EmojiCreateSchema { + name?: string; + image: string; + require_colons?: boolean | null; + roles?: string[]; +} diff --git a/src/util/schemas/EmojiModifySchema.ts b/src/util/schemas/EmojiModifySchema.ts new file mode 100644
index 00000000..05d2d395 --- /dev/null +++ b/src/util/schemas/EmojiModifySchema.ts
@@ -0,0 +1,4 @@ +export interface EmojiModifySchema { + name?: string; + roles?: string[]; +} diff --git a/src/util/schemas/GuildCreateSchema.ts b/src/util/schemas/GuildCreateSchema.ts new file mode 100644
index 00000000..e4855119 --- /dev/null +++ b/src/util/schemas/GuildCreateSchema.ts
@@ -0,0 +1,14 @@ +import { ChannelModifySchema } from "."; + +export interface GuildCreateSchema { + /** + * @maxLength 100 + */ + name: string; + region?: string; + icon?: string | null; + channels?: ChannelModifySchema[]; + guild_template_code?: string; + system_channel_id?: string; + rules_channel_id?: string; +} diff --git a/src/util/schemas/GuildTemplateCreateSchema.ts b/src/util/schemas/GuildTemplateCreateSchema.ts new file mode 100644
index 00000000..59db8428 --- /dev/null +++ b/src/util/schemas/GuildTemplateCreateSchema.ts
@@ -0,0 +1,4 @@ +export interface GuildTemplateCreateSchema { + name: string; + avatar?: string | null; +} diff --git a/src/util/schemas/GuildUpdateSchema.ts b/src/util/schemas/GuildUpdateSchema.ts new file mode 100644
index 00000000..86527cf1 --- /dev/null +++ b/src/util/schemas/GuildUpdateSchema.ts
@@ -0,0 +1,18 @@ +import { GuildCreateSchema } from "."; + +export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels" | "name"> { + name?: string; + banner?: string | null; + splash?: string | null; + description?: string; + features?: string[]; + verification_level?: number; + default_message_notifications?: number; + system_channel_flags?: number; + explicit_content_filter?: number; + public_updates_channel_id?: string; + afk_timeout?: number; + afk_channel_id?: string; + preferred_locale?: string; + premium_progress_bar_enabled?: boolean; +} diff --git a/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts b/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts new file mode 100644
index 00000000..c8b8ba4e --- /dev/null +++ b/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts
@@ -0,0 +1,10 @@ +export interface GuildUpdateWelcomeScreenSchema { + welcome_channels?: { + channel_id: string; + description: string; + emoji_id?: string; + emoji_name: string; + }[]; + enabled?: boolean; + description?: string; +} diff --git a/gateway/src/schema/Identify.ts b/src/util/schemas/IdentifySchema.ts
index 21141321..bb5ae0c8 100644 --- a/gateway/src/schema/Identify.ts +++ b/src/util/schemas/IdentifySchema.ts
@@ -1,8 +1,8 @@ -import { ActivitySchema } from "./Activity"; +import { ActivitySchema } from "./ActivitySchema"; export const IdentifySchema = { token: String, - $intents: BigInt, // discord uses a Integer for bitfields we use bigints tho. | instanceOf will automatically convert the Number to a BigInt + $intents: String, // discord uses a Integer for bitfields we use bigints tho. | instanceOf will automatically convert the Number to a BigInt $properties: Object, // { // // discord uses $ in the property key for bots, so we need to double prefix it, because instanceOf treats $ (prefix) as a optional key @@ -33,7 +33,7 @@ export const IdentifySchema = { $presence: ActivitySchema, $compress: Boolean, $large_threshold: Number, - $shard: [BigInt, BigInt], + $shard: [Number, Number], $guild_subscriptions: Boolean, $capabilities: Number, $client_state: { @@ -41,10 +41,10 @@ export const IdentifySchema = { $highest_last_message_id: String, $read_state_version: Number, $user_guild_settings_version: Number, - $user_settings_version: undefined, + $user_settings_version: undefined }, $v: Number, - $version: Number, + $version: Number }; export interface IdentifySchema { @@ -71,11 +71,11 @@ export interface IdentifySchema { client_version?: string; system_locale?: string; }; - intents?: bigint; // discord uses a Integer for bitfields we use bigints tho. | instanceOf will automatically convert the Number to a BigInt + intents?: string; // discord uses a Integer for bitfields we use bigints tho. | instanceOf will automatically convert the Number to a BigInt presence?: ActivitySchema; compress?: boolean; large_threshold?: number; - shard?: [bigint, bigint]; + shard?: [number, number]; guild_subscriptions?: boolean; capabilities?: number; client_state?: { diff --git a/src/util/schemas/InviteCreateSchema.ts b/src/util/schemas/InviteCreateSchema.ts new file mode 100644
index 00000000..cac11147 --- /dev/null +++ b/src/util/schemas/InviteCreateSchema.ts
@@ -0,0 +1,11 @@ +export interface InviteCreateSchema { + target_user_id?: string; + target_type?: string; + validate?: string; // ? what is this + max_age?: number; + max_uses?: number; + temporary?: boolean; + unique?: boolean; + target_user?: string; + target_user_type?: number; +} diff --git a/gateway/src/schema/LazyRequest.ts b/src/util/schemas/LazyRequestSchema.ts
index 1fe658bb..fbed5c5b 100644 --- a/gateway/src/schema/LazyRequest.ts +++ b/src/util/schemas/LazyRequestSchema.ts
@@ -15,5 +15,5 @@ export const LazyRequest = { $typing: Boolean, $threads: Boolean, $members: [] as any[], - $thread_member_lists: [] as any[], + $thread_member_lists: [] as any[] }; diff --git a/src/util/schemas/LoginSchema.ts b/src/util/schemas/LoginSchema.ts new file mode 100644
index 00000000..dc889d94 --- /dev/null +++ b/src/util/schemas/LoginSchema.ts
@@ -0,0 +1,8 @@ +export interface LoginSchema { + login: string; + password: string; + undelete?: boolean; + captcha_key?: string; + login_source?: string; + gift_code_sku_id?: string; +} diff --git a/src/util/schemas/MemberChangeSchema.ts b/src/util/schemas/MemberChangeSchema.ts new file mode 100644
index 00000000..db434538 --- /dev/null +++ b/src/util/schemas/MemberChangeSchema.ts
@@ -0,0 +1,3 @@ +export interface MemberChangeSchema { + roles?: string[]; +} diff --git a/src/util/schemas/MemberNickChangeSchema.ts b/src/util/schemas/MemberNickChangeSchema.ts new file mode 100644
index 00000000..d863038c --- /dev/null +++ b/src/util/schemas/MemberNickChangeSchema.ts
@@ -0,0 +1,3 @@ +export interface MemberNickChangeSchema { + nick: string; +} diff --git a/src/util/schemas/MessageAcknowledgeSchema.ts b/src/util/schemas/MessageAcknowledgeSchema.ts new file mode 100644
index 00000000..3f4eb2b6 --- /dev/null +++ b/src/util/schemas/MessageAcknowledgeSchema.ts
@@ -0,0 +1,8 @@ +// TODO: public read receipts & privacy scoping +// TODO: send read state event to all channel members +// TODO: advance-only notification cursor + +export interface MessageAcknowledgeSchema { + manual?: boolean; + mention_count?: number; +} diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts new file mode 100644
index 00000000..bf3470bb --- /dev/null +++ b/src/util/schemas/MessageCreateSchema.ts
@@ -0,0 +1,33 @@ +import { Embed } from "@fosscord/util"; + +export interface MessageCreateSchema { + type?: number; + content?: string; + nonce?: string; + channel_id?: string; + tts?: boolean; + flags?: string; + embeds?: Embed[]; + embed?: Embed; + // TODO: ^ embed is deprecated in favor of embeds (https://discord.com/developers/docs/resources/channel#message-object) + allowed_mentions?: { + parse?: string[]; + roles?: string[]; + users?: string[]; + replied_user?: boolean; + }; + message_reference?: { + message_id: string; + channel_id: string; + guild_id?: string; + fail_if_not_exists?: boolean; + }; + payload_json?: string; + file?: any; + /** + TODO: we should create an interface for attachments + TODO: OpenWAAO<-->attachment-style metadata conversion + **/ + attachments?: any[]; + sticker_ids?: string[]; +} diff --git a/src/util/schemas/MfaCodesSchema.ts b/src/util/schemas/MfaCodesSchema.ts new file mode 100644
index 00000000..ac05b9a4 --- /dev/null +++ b/src/util/schemas/MfaCodesSchema.ts
@@ -0,0 +1,4 @@ +export interface MfaCodesSchema { + password: string; + regenerate?: boolean; +} diff --git a/src/util/schemas/ModifyGuildStickerSchema.ts b/src/util/schemas/ModifyGuildStickerSchema.ts new file mode 100644
index 00000000..159cc44f --- /dev/null +++ b/src/util/schemas/ModifyGuildStickerSchema.ts
@@ -0,0 +1,15 @@ +export interface ModifyGuildStickerSchema { + /** + * @minLength 2 + * @maxLength 30 + */ + name: string; + /** + * @maxLength 100 + */ + description?: string; + /** + * @maxLength 200 + */ + tags: string; +} diff --git a/src/util/schemas/PruneSchema.ts b/src/util/schemas/PruneSchema.ts new file mode 100644
index 00000000..bea5e2b4 --- /dev/null +++ b/src/util/schemas/PruneSchema.ts
@@ -0,0 +1,6 @@ +export interface PruneSchema { + /** + * @min 0 + */ + days: number; +} diff --git a/src/util/schemas/PurgeSchema.ts b/src/util/schemas/PurgeSchema.ts new file mode 100644
index 00000000..f5ab0a20 --- /dev/null +++ b/src/util/schemas/PurgeSchema.ts
@@ -0,0 +1,4 @@ +export interface PurgeSchema { + before: string; + after: string; +} diff --git a/src/util/schemas/RegisterSchema.ts b/src/util/schemas/RegisterSchema.ts new file mode 100644
index 00000000..9bbd9db5 --- /dev/null +++ b/src/util/schemas/RegisterSchema.ts
@@ -0,0 +1,26 @@ +export interface RegisterSchema { + /** + * @minLength 2 + * @maxLength 32 + */ + username: string; + /** + * @minLength 1 + * @maxLength 72 + */ + password?: string; + consent: boolean; + /** + * @TJS-format email + */ + email?: string; + fingerprint?: string; + invite?: string; + /** + * @TJS-type string + */ + date_of_birth?: Date; // "2000-04-03" + gift_code_sku_id?: string; + captcha_key?: string; + promotional_email_opt_in?: boolean; +} diff --git a/src/util/schemas/RelationshipPostSchema.ts b/src/util/schemas/RelationshipPostSchema.ts new file mode 100644
index 00000000..774c67f6 --- /dev/null +++ b/src/util/schemas/RelationshipPostSchema.ts
@@ -0,0 +1,4 @@ +export interface RelationshipPostSchema { + discriminator: string; + username: string; +} diff --git a/src/util/schemas/RelationshipPutSchema.ts b/src/util/schemas/RelationshipPutSchema.ts new file mode 100644
index 00000000..0a7f9720 --- /dev/null +++ b/src/util/schemas/RelationshipPutSchema.ts
@@ -0,0 +1,5 @@ +import { RelationshipType } from "@fosscord/util"; + +export interface RelationshipPutSchema { + type?: RelationshipType; +} diff --git a/src/util/schemas/RoleModifySchema.ts b/src/util/schemas/RoleModifySchema.ts new file mode 100644
index 00000000..f3f4a20e --- /dev/null +++ b/src/util/schemas/RoleModifySchema.ts
@@ -0,0 +1,10 @@ +export interface RoleModifySchema { + name?: string; + permissions?: string; + color?: number; + hoist?: boolean; // whether the role should be displayed separately in the sidebar + mentionable?: boolean; // whether the role should be mentionable + position?: number; + icon?: string; + unicode_emoji?: string; +} diff --git a/src/util/schemas/RolePositionUpdateSchema.ts b/src/util/schemas/RolePositionUpdateSchema.ts new file mode 100644
index 00000000..993d1ae0 --- /dev/null +++ b/src/util/schemas/RolePositionUpdateSchema.ts
@@ -0,0 +1,4 @@ +export type RolePositionUpdateSchema = { + id: string; + position: number; +}[]; diff --git a/src/util/schemas/TemplateCreateSchema.ts b/src/util/schemas/TemplateCreateSchema.ts new file mode 100644
index 00000000..160934f5 --- /dev/null +++ b/src/util/schemas/TemplateCreateSchema.ts
@@ -0,0 +1,4 @@ +export interface TemplateCreateSchema { + name: string; + description?: string; +} diff --git a/src/util/schemas/TemplateModifySchema.ts b/src/util/schemas/TemplateModifySchema.ts new file mode 100644
index 00000000..f9c9d14b --- /dev/null +++ b/src/util/schemas/TemplateModifySchema.ts
@@ -0,0 +1,4 @@ +export interface TemplateModifySchema { + name: string; + description?: string; +} diff --git a/src/util/schemas/TotpDisableSchema.ts b/src/util/schemas/TotpDisableSchema.ts new file mode 100644
index 00000000..51446e1c --- /dev/null +++ b/src/util/schemas/TotpDisableSchema.ts
@@ -0,0 +1,3 @@ +export interface TotpDisableSchema { + code: string; +} diff --git a/src/util/schemas/TotpEnableSchema.ts b/src/util/schemas/TotpEnableSchema.ts new file mode 100644
index 00000000..4e3551d9 --- /dev/null +++ b/src/util/schemas/TotpEnableSchema.ts
@@ -0,0 +1,5 @@ +export interface TotpEnableSchema { + password: string; + code?: string; + secret?: string; +} diff --git a/src/util/schemas/TotpSchema.ts b/src/util/schemas/TotpSchema.ts new file mode 100644
index 00000000..941a92ec --- /dev/null +++ b/src/util/schemas/TotpSchema.ts
@@ -0,0 +1,6 @@ +export interface TotpSchema { + code: string; + ticket: string; + gift_code_sku_id?: string | null; + login_source?: string | null; +} diff --git a/src/util/schemas/UserModifySchema.ts b/src/util/schemas/UserModifySchema.ts new file mode 100644
index 00000000..622497d9 --- /dev/null +++ b/src/util/schemas/UserModifySchema.ts
@@ -0,0 +1,19 @@ +export interface UserModifySchema { + /** + * @minLength 1 + * @maxLength 100 + */ + username?: string; + discriminator?: string; + avatar?: string | null; + /** + * @maxLength 1024 + */ + bio?: string; + accent_color?: number; + banner?: string | null; + password?: string; + new_password?: string; + code?: string; + email?: string; +} diff --git a/src/util/schemas/UserSettingsSchema.ts b/src/util/schemas/UserSettingsSchema.ts new file mode 100644
index 00000000..eb9b316d --- /dev/null +++ b/src/util/schemas/UserSettingsSchema.ts
@@ -0,0 +1,3 @@ +import { UserSettings } from "@fosscord/util"; + +export interface UserSettingsSchema extends Partial<UserSettings> {} diff --git a/src/util/schemas/VanityUrlSchema.ts b/src/util/schemas/VanityUrlSchema.ts new file mode 100644
index 00000000..4dd9b9da --- /dev/null +++ b/src/util/schemas/VanityUrlSchema.ts
@@ -0,0 +1,7 @@ +export interface VanityUrlSchema { + /** + * @minLength 1 + * @maxLength 20 + */ + code?: string; +} diff --git a/src/util/schemas/VoiceStateUpdateSchema.ts b/src/util/schemas/VoiceStateUpdateSchema.ts new file mode 100644
index 00000000..ea286b1a --- /dev/null +++ b/src/util/schemas/VoiceStateUpdateSchema.ts
@@ -0,0 +1,18 @@ +export const VoiceStateUpdateSchema = { + $guild_id: String, + $channel_id: String, + self_mute: Boolean, + self_deaf: Boolean, + self_video: Boolean +}; + +//TODO need more testing when community guild and voice stage channel are working +export interface VoiceStateUpdateSchema { + channel_id: string; + guild_id?: string; + suppress?: boolean; + request_to_speak_timestamp?: Date; + self_mute?: boolean; + self_deaf?: boolean; + self_video?: boolean; +} diff --git a/src/util/schemas/WebhookCreateSchema.ts b/src/util/schemas/WebhookCreateSchema.ts new file mode 100644
index 00000000..12ab1869 --- /dev/null +++ b/src/util/schemas/WebhookCreateSchema.ts
@@ -0,0 +1,8 @@ +// TODO: webhooks +export interface WebhookCreateSchema { + /** + * @maxLength 80 + */ + name: string; + avatar?: string; +} diff --git a/src/util/schemas/WidgetModifySchema.ts b/src/util/schemas/WidgetModifySchema.ts new file mode 100644
index 00000000..26d4504f --- /dev/null +++ b/src/util/schemas/WidgetModifySchema.ts
@@ -0,0 +1,4 @@ +export interface WidgetModifySchema { + enabled: boolean; // whether the widget is enabled + channel_id: string; // the widget channel id +} diff --git a/src/util/schemas/index.ts b/src/util/schemas/index.ts new file mode 100644
index 00000000..a15ab4b0 --- /dev/null +++ b/src/util/schemas/index.ts
@@ -0,0 +1,43 @@ +export * from "./ActivitySchema"; +export * from "./BanCreateSchema"; +export * from "./BanModeratorSchema"; +export * from "./BanRegistrySchema"; +export * from "./BulkDeleteSchema"; +export * from "./ChannelModifySchema"; +export * from "./ChannelPermissionOverwriteSchema"; +export * from "./ChannelReorderSchema"; +export * from "./DmChannelCreateSchema"; +export * from "./EmojiCreateSchema"; +export * from "./EmojiModifySchema"; +export * from "./GuildCreateSchema"; +export * from "./GuildTemplateCreateSchema"; +export * from "./GuildUpdateSchema"; +export * from "./GuildUpdateWelcomeScreenSchema"; +export * from "./IdentifySchema"; +export * from "./InviteCreateSchema"; +export * from "./LazyRequestSchema"; +export * from "./LoginSchema"; +export * from "./MemberChangeSchema"; +export * from "./MemberNickChangeSchema"; +export * from "./MessageAcknowledgeSchema"; +export * from "./MessageCreateSchema"; +export * from "./MfaCodesSchema"; +export * from "./ModifyGuildStickerSchema"; +export * from "./PruneSchema"; +export * from "./PurgeSchema"; +export * from "./RegisterSchema"; +export * from "./RelationshipPostSchema"; +export * from "./RelationshipPutSchema"; +export * from "./RoleModifySchema"; +export * from "./RolePositionUpdateSchema"; +export * from "./TemplateCreateSchema"; +export * from "./TemplateModifySchema"; +export * from "./TotpDisableSchema"; +export * from "./TotpEnableSchema"; +export * from "./TotpSchema"; +export * from "./UserModifySchema"; +export * from "./UserSettingsSchema"; +export * from "./VanityUrlSchema"; +export * from "./VoiceStateUpdateSchema"; +export * from "./WebhookCreateSchema"; +export * from "./WidgetModifySchema"; diff --git a/util/src/util/ApiError.ts b/src/util/util/ApiError.ts
index f1a9b4f6..c133e6e7 100644 --- a/util/src/util/ApiError.ts +++ b/src/util/util/ApiError.ts
@@ -9,8 +9,7 @@ export class ApiError extends Error { } withDefaultParams(): ApiError { - if (this.defaultParams) - return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus); + if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus); return this; } diff --git a/util/src/util/Array.ts b/src/util/util/Array.ts
index 5a45d1b5..5a45d1b5 100644 --- a/util/src/util/Array.ts +++ b/src/util/util/Array.ts
diff --git a/util/src/util/AutoUpdate.ts b/src/util/util/AutoUpdate.ts
index 531bd8b7..08418040 100644 --- a/util/src/util/AutoUpdate.ts +++ b/src/util/util/AutoUpdate.ts
@@ -1,13 +1,12 @@ -import "missing-native-js-functions"; -import fetch from "node-fetch"; -import ProxyAgent from 'proxy-agent'; -import readline from "readline"; import fs from "fs/promises"; +import fetch from "node-fetch"; import path from "path"; +import ProxyAgent from "proxy-agent"; +import readline from "readline"; const rl = readline.createInterface({ input: process.stdin, - output: process.stdout, + output: process.stdout }); export function enableAutoUpdate(opts: { @@ -18,7 +17,7 @@ export function enableAutoUpdate(opts: { downloadType?: "zip"; }) { if (!opts.checkInterval) return; - var interval = 1000 * 60 * 60 * 24; + let interval = 1000 * 60 * 60 * 24; if (typeof opts.checkInterval === "number") opts.checkInterval = 1000 * interval; const i = setInterval(async () => { @@ -76,7 +75,7 @@ async function getLatestVersion(url: string) { try { const agent = new ProxyAgent(); const response = await fetch(url, { agent }); - const content = await response.json(); + const content: any = await response.json(); return content.version; } catch (error) { throw new Error("[Auto update] check failed for " + url); diff --git a/util/src/util/BitField.ts b/src/util/util/BitField.ts
index fb887e05..306bfb32 100644 --- a/util/src/util/BitField.ts +++ b/src/util/util/BitField.ts
@@ -138,6 +138,9 @@ export class BitField { return bit.map((p) => resolve.call(this, p)).reduce((prev, p) => BigInt(prev) | BigInt(p), BigInt(0)); } if (typeof bit === "string" && typeof FLAGS[bit] !== "undefined") return FLAGS[bit]; + if (bit === "0") return BigInt(0); //special case: 0 + if (typeof bit === "string") return BigInt(bit); //last ditch effort... + if (/--debug|--inspect/.test(process.execArgv.join(" "))) debugger; //if you're here, we have an invalid bitfield... if bit is 0, thats fine, I guess... throw new RangeError("BITFIELD_INVALID: " + bit); } } diff --git a/util/src/util/Categories.ts b/src/util/util/Categories.ts
index a3c69da7..cd706a8a 100644 --- a/util/src/util/Categories.ts +++ b/src/util/util/Categories.ts
@@ -1 +1 @@ -//TODO: populate default discord categories + init, get and set methods \ No newline at end of file +//TODO: populate default discord categories + init, get and set methods diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts new file mode 100644
index 00000000..cc7090a6 --- /dev/null +++ b/src/util/util/Config.ts
@@ -0,0 +1,105 @@ +import fs from "fs"; +import path from "path"; +import { OrmUtils } from "."; +import { ConfigValue } from "../config"; +import { ConfigEntity } from "../entities/Config"; + +// TODO: yaml instead of json +const overridePath = process.env.CONFIG_PATH ?? ""; + +let config: ConfigValue; +let pairs: ConfigEntity[]; + +// TODO: use events to inform about config updates +// Config keys are separated with _ + +export const Config = { + init: async function init() { + if (config) return config; + console.log("[Config] Loading configuration..."); + pairs = await ConfigEntity.find(); + config = pairsToConfig(pairs); + //config = (config || {}).merge(new ConfigValue()); + config = OrmUtils.mergeDeep(new ConfigValue(), config); + + if (process.env.CONFIG_PATH) + try { + const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" })); + config = OrmUtils.mergeDeep(config, overrideConfig); + } catch (error) { + fs.writeFileSync(overridePath, JSON.stringify(config, null, 4)); + } + + if (fs.existsSync(path.join(process.cwd(), "initial.json"))) + try { + console.log("[Config] Found initial configuration, merging..."); + const overrideConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), "initial.json"), { encoding: "utf8" })); + config = OrmUtils.mergeDeep(config, overrideConfig); + fs.rmSync(path.join(process.cwd(), "initial.json")); + } catch (error) { + fs.writeFileSync(path.join(process.cwd(), "failed.conf"), JSON.stringify(config, null, 4)); + } + + return this.set(config); + }, + get: function get() { + if (!config) { + if (/--debug|--inspect/.test(process.execArgv.join(" "))) + console.log( + "Oops.. trying to get config without config existing... Returning defaults... (Is the database still initialising?)" + ); + return new ConfigValue(); + } + return config; + }, + set: function set(val: Partial<ConfigValue>) { + if (!config || !val) return; + config = val.merge(config); + + return applyConfig(config); + } +}; + +function applyConfig(val: ConfigValue) { + async function apply(obj: any, key = ""): Promise<any> { + if (typeof obj === "object" && obj !== null) + return Promise.all(Object.keys(obj).map((k) => apply(obj[k], key ? `${key}_${k}` : k))); + + let pair = pairs.find((x) => x.key === key); + if (!pair) pair = new ConfigEntity(); + + pair.key = key; + pair.value = obj; + return pair.save(); + } + if (process.env.CONFIG_PATH) { + if (/--debug|--inspect/.test(process.execArgv.join(" "))) console.log(`Writing config: ${process.env.CONFIG_PATH}`); + fs.writeFileSync(overridePath, JSON.stringify(val, null, 4)); + } + + return apply(val); +} + +function pairsToConfig(pairs: ConfigEntity[]) { + let value: any = {}; + + pairs.forEach((p) => { + const keys = p.key.split("_"); + let obj = value; + let prev = ""; + let prevObj = obj; + let i = 0; + + for (const key of keys) { + if (!isNaN(Number(key)) && !prevObj[prev]?.length) prevObj[prev] = obj = []; + if (i++ === keys.length - 1) obj[key] = p.value; + else if (!obj[key]) obj[key] = {}; + + prev = key; + prevObj = obj; + obj = obj[key]; + } + }); + + return value as ConfigValue; +} diff --git a/util/src/util/Constants.ts b/src/util/util/Constants.ts
index a5d3fcd2..f7aff26a 100644 --- a/util/src/util/Constants.ts +++ b/src/util/util/Constants.ts
@@ -6,7 +6,7 @@ export const WSCodes = { 4010: "SHARDING_INVALID", 4011: "SHARDING_REQUIRED", 4013: "INVALID_INTENTS", - 4014: "DISALLOWED_INTENTS", + 4014: "DISALLOWED_INTENTS" }; /** @@ -31,7 +31,7 @@ export const WsStatus = { DISCONNECTED: 5, WAITING_FOR_GUILDS: 6, IDENTIFYING: 7, - RESUMING: 8, + RESUMING: 8 }; /** @@ -48,7 +48,7 @@ export const VoiceStatus = { CONNECTING: 1, AUTHENTICATING: 2, RECONNECTING: 3, - DISCONNECTED: 4, + DISCONNECTED: 4 }; export const OPCodes = { @@ -63,7 +63,7 @@ export const OPCodes = { REQUEST_GUILD_MEMBERS: 8, INVALID_SESSION: 9, HELLO: 10, - HEARTBEAT_ACK: 11, + HEARTBEAT_ACK: 11 }; export const VoiceOPCodes = { @@ -75,7 +75,7 @@ export const VoiceOPCodes = { SPEAKING: 5, HELLO: 8, CLIENT_CONNECT: 12, - CLIENT_DISCONNECT: 13, + CLIENT_DISCONNECT: 13 }; export const Events = { @@ -133,7 +133,7 @@ export const Events = { SHARD_READY: "shardReady", SHARD_RESUME: "shardResume", INVALIDATED: "invalidated", - RAW: "raw", + RAW: "raw" }; export const ShardEvents = { @@ -142,7 +142,7 @@ export const ShardEvents = { INVALID_SESSION: "invalidSession", READY: "ready", RESUMED: "resumed", - ALL_READY: "allReady", + ALL_READY: "allReady" }; /** @@ -234,7 +234,7 @@ export const WSEvents = keyMirror([ "TYPING_START", "VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE", - "WEBHOOKS_UPDATE", + "WEBHOOKS_UPDATE" ]); /** @@ -277,7 +277,7 @@ export const MessageTypes = [ null, null, null, - "REPLY", + "REPLY" ]; /** @@ -286,9 +286,7 @@ export const MessageTypes = [ * * REPLY * @typedef {string} SystemMessageType */ -export const SystemMessageTypes = MessageTypes.filter( - (type: string | null) => type && type !== "DEFAULT" && type !== "REPLY" -); +export const SystemMessageTypes = MessageTypes.filter((type: string | null) => type && type !== "DEFAULT" && type !== "REPLY"); /** * <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info> @@ -310,12 +308,12 @@ export const ChannelTypes = { GROUP: 3, CATEGORY: 4, NEWS: 5, - STORE: 6, + STORE: 6 }; export const ClientApplicationAssetTypes = { SMALL: 1, - BIG: 2, + BIG: 2 }; export const Colors = { @@ -347,7 +345,7 @@ export const Colors = { BLURPLE: 0x7289da, GREYPLE: 0x99aab5, DARK_BUT_NOT_BLACK: 0x2c2f33, - NOT_QUITE_BLACK: 0x23272a, + NOT_QUITE_BLACK: 0x23272a }; /** @@ -556,14 +554,8 @@ export const DiscordApiErrors = { UNKNOWN_GUILD_SCHEDULED_EVENT_USER: new ApiError("Unknown Guild Scheduled Event User", 10071), BOT_PROHIBITED_ENDPOINT: new ApiError("Bots cannot use this endpoint", 20001), BOT_ONLY_ENDPOINT: new ApiError("Only bots can use this endpoint", 20002), - EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError( - "Explicit content cannot be sent to the desired recipient(s)", - 20009 - ), - ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError( - "You are not authorized to perform this action on this application", - 20012 - ), + EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError("Explicit content cannot be sent to the desired recipient(s)", 20009), + ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError("You are not authorized to perform this action on this application", 20012), SLOWMODE_RATE_LIMIT: new ApiError("This action cannot be performed due to slowmode rate limit", 20016), ONLY_OWNER: new ApiError("Only the owner of this account can perform this action", 20018), ANNOUNCEMENT_RATE_LIMITS: new ApiError("This message cannot be edited due to announcement rate limits", 20022), @@ -576,40 +568,25 @@ export const DiscordApiErrors = { MAXIMUM_GUILDS: new ApiError("Maximum number of guilds reached ({})", 30001, undefined, ["100"]), MAXIMUM_FRIENDS: new ApiError("Maximum number of friends reached ({})", 30002, undefined, ["1000"]), MAXIMUM_PINS: new ApiError("Maximum number of pins reached for the channel ({})", 30003, undefined, ["50"]), - MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError("Maximum number of recipients reached ({})", 30004, undefined, [ - "10", - ]), + MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError("Maximum number of recipients reached ({})", 30004, undefined, ["10"]), MAXIMUM_ROLES: new ApiError("Maximum number of guild roles reached ({})", 30005, undefined, ["250"]), MAXIMUM_WEBHOOKS: new ApiError("Maximum number of webhooks reached ({})", 30007, undefined, ["10"]), MAXIMUM_NUMBER_OF_EMOJIS_REACHED: new ApiError("Maximum number of emojis reached", 30008), MAXIMUM_REACTIONS: new ApiError("Maximum number of reactions reached ({})", 30010, undefined, ["20"]), MAXIMUM_CHANNELS: new ApiError("Maximum number of guild channels reached ({})", 30013, undefined, ["500"]), - MAXIMUM_ATTACHMENTS: new ApiError("Maximum number of attachments in a message reached ({})", 30015, undefined, [ - "10", - ]), + MAXIMUM_ATTACHMENTS: new ApiError("Maximum number of attachments in a message reached ({})", 30015, undefined, ["10"]), MAXIMUM_INVITES: new ApiError("Maximum number of invites reached ({})", 30016, undefined, ["1000"]), MAXIMUM_ANIMATED_EMOJIS: new ApiError("Maximum number of animated emojis reached", 30018), MAXIMUM_SERVER_MEMBERS: new ApiError("Maximum number of server members reached", 30019), - MAXIMUM_SERVER_CATEGORIES: new ApiError( - "Maximum number of server categories has been reached ({})", - 30030, - undefined, - ["5"] - ), + MAXIMUM_SERVER_CATEGORIES: new ApiError("Maximum number of server categories has been reached ({})", 30030, undefined, ["5"]), GUILD_ALREADY_HAS_TEMPLATE: new ApiError("Guild already has a template", 30031), MAXIMUM_THREAD_PARTICIPANTS: new ApiError("Max number of thread participants has been reached", 30033), - MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError( - "Maximum number of bans for non-guild members have been exceeded", - 30035 - ), + MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError("Maximum number of bans for non-guild members have been exceeded", 30035), MAXIMUM_BANS_FETCHES: new ApiError("Maximum number of bans fetches has been reached", 30037), MAXIMUM_STICKERS: new ApiError("Maximum number of stickers reached", 30039), MAXIMUM_PRUNE_REQUESTS: new ApiError("Maximum number of prune requests has been reached. Try again later", 30040), UNAUTHORIZED: new ApiError("Unauthorized. Provide a valid token and try again", 40001), - ACCOUNT_VERIFICATION_REQUIRED: new ApiError( - "You need to verify your account in order to perform this action", - 40002 - ), + ACCOUNT_VERIFICATION_REQUIRED: new ApiError("You need to verify your account in order to perform this action", 40002), OPENING_DIRECT_MESSAGES_TOO_FAST: new ApiError("You are opening direct messages too fast", 40003), REQUEST_ENTITY_TOO_LARGE: new ApiError("Request entity too large. Try sending something smaller in size", 40005), FEATURE_TEMPORARILY_DISABLED: new ApiError("This feature has been temporarily disabled server-side", 40006), @@ -625,10 +602,7 @@ export const DiscordApiErrors = { CANNOT_SEND_EMPTY_MESSAGE: new ApiError("Cannot send an empty message", 50006), CANNOT_MESSAGE_USER: new ApiError("Cannot send messages to this user", 50007), CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: new ApiError("Cannot send messages in a voice channel", 50008), - CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError( - "Channel verification level is too high for you to gain access", - 50009 - ), + CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError("Channel verification level is too high for you to gain access", 50009), OAUTH2_APPLICATION_BOT_ABSENT: new ApiError("OAuth2 application does not have a bot", 50010), MAXIMUM_OAUTH2_APPLICATIONS: new ApiError("OAuth2 application limit reached", 50011), INVALID_OAUTH_STATE: new ApiError("Invalid OAuth2 state", 50012), @@ -641,10 +615,7 @@ export const DiscordApiErrors = { undefined, ["2", "100"] ), - CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError( - "A message can only be pinned to the channel it was sent in", - 50019 - ), + CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError("A message can only be pinned to the channel it was sent in", 50019), INVALID_OR_TAKEN_INVITE_CODE: new ApiError("Invite code was either invalid or taken", 50020), CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: new ApiError("Cannot execute action on a system message", 50021), CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE: new ApiError("Cannot execute action on this channel type", 50024), @@ -658,34 +629,22 @@ export const DiscordApiErrors = { "Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided", 50035 ), - INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError( - "An invite was accepted to a guild the application's bot is not in", - 50036 - ), + INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError("An invite was accepted to a guild the application's bot is not in", 50036), INVALID_API_VERSION: new ApiError("Invalid API version provided", 50041), FILE_EXCEEDS_MAXIMUM_SIZE: new ApiError("File uploaded exceeds the maximum size", 50045), INVALID_FILE_UPLOADED: new ApiError("Invalid file uploaded", 50046), CANNOT_SELF_REDEEM_GIFT: new ApiError("Cannot self-redeem this gift", 50054), PAYMENT_SOURCE_REQUIRED: new ApiError("Payment source required to redeem gift", 50070), - CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError( - "Cannot delete a channel required for Community guilds", - 50074 - ), + CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError("Cannot delete a channel required for Community guilds", 50074), INVALID_STICKER_SENT: new ApiError("Invalid sticker sent", 50081), CANNOT_EDIT_ARCHIVED_THREAD: new ApiError( "Tried to perform an operation on an archived thread, such as editing a message or adding a user to the thread", 50083 ), INVALID_THREAD_NOTIFICATION_SETTINGS: new ApiError("Invalid thread notification settings", 50084), - BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError( - "before value is earlier than the thread creation date", - 50085 - ), + BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError("before value is earlier than the thread creation date", 50085), SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION: new ApiError("This server is not available in your location", 50095), - SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError( - "This server needs monetization enabled in order to perform this action", - 50097 - ), + SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError("This server needs monetization enabled in order to perform this action", 50097), TWO_FACTOR_REQUIRED: new ApiError("Two factor is required for this operation", 60003), NO_USERS_WITH_DISCORDTAG_EXIST: new ApiError("No users with DiscordTag exist", 80004), REACTION_BLOCKED: new ApiError("Reaction was blocked", 90001), @@ -694,33 +653,17 @@ export const DiscordApiErrors = { THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE: new ApiError("A thread has already been created for this message", 160004), THREAD_IS_LOCKED: new ApiError("Thread is locked", 160005), MAXIMUM_NUMBER_OF_ACTIVE_THREADS: new ApiError("Maximum number of active threads reached", 160006), - MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError( - "Maximum number of active announcement threads reached", - 160007 - ), + MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError("Maximum number of active announcement threads reached", 160007), INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE: new ApiError("Invalid JSON for uploaded Lottie file", 170001), - LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError( - "Uploaded Lotties cannot contain rasterized images such as PNG or JPEG", - 170002 - ), + LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError("Uploaded Lotties cannot contain rasterized images such as PNG or JPEG", 170002), STICKER_MAXIMUM_FRAMERATE: new ApiError("Sticker maximum framerate exceeded", 170003), - STICKER_MAXIMUM_FRAME_COUNT: new ApiError("Sticker frame count exceeds maximum of {} frames", 170004, undefined, [ - "1000", - ]), + STICKER_MAXIMUM_FRAME_COUNT: new ApiError("Sticker frame count exceeds maximum of {} frames", 170004, undefined, ["1000"]), LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS: new ApiError("Lottie animation maximum dimensions exceeded", 170005), - STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError( - "Sticker frame rate is either too small or too large", - 170006 - ), - STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError( - "Sticker animation duration exceeds maximum of {} seconds", - 170007, - undefined, - ["5"] - ), + STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError("Sticker frame rate is either too small or too large", 170006), + STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError("Sticker animation duration exceeds maximum of {} seconds", 170007, undefined, ["5"]), //Other errors - UNKNOWN_VOICE_STATE: new ApiError("Unknown Voice State", 10065, 404), + UNKNOWN_VOICE_STATE: new ApiError("Unknown Voice State", 10065, 404) }; /** @@ -746,7 +689,7 @@ export const FosscordApiErrors = { CANNOT_BACKFILL_TO_THE_FUTURE: new ApiError("You cannot backfill messages in the future", 55003), CANNOT_GRANT_PERMISSIONS_EXCEEDING_RIGHTS: new ApiError("You cannot grant permissions exceeding your own rights", 50050), ROUTES_LOOPING: new ApiError("Loops in the route definition ({})", 50060, undefined, [""]), - CANNOT_REMOVE_ROUTE: new ApiError("Cannot remove message route while it is in effect and being used", 50061), + CANNOT_REMOVE_ROUTE: new ApiError("Cannot remove message route while it is in effect and being used", 50061) }; /** @@ -765,11 +708,7 @@ export const DefaultMessageNotifications = ["ALL", "MENTIONS", "MUTED"]; * * INSERTED (Fosscord extension) * @typedef {string} MembershipStates */ -export const MembershipStates = [ - "INSERTED", - "INVITED", - "ACCEPTED", -]; +export const MembershipStates = ["INSERTED", "INVITED", "ACCEPTED"]; /** * The value set for a webhook's type: @@ -778,15 +717,10 @@ export const MembershipStates = [ * * Custom (Fosscord extension) * @typedef {string} WebhookTypes */ -export const WebhookTypes = [ - "Custom", - "Incoming", - "Channel Follower", -]; +export const WebhookTypes = ["Custom", "Incoming", "Channel Follower"]; function keyMirror(arr: string[]) { let tmp = Object.create(null); for (const value of arr) tmp[value] = value; return tmp; } - diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts new file mode 100644
index 00000000..b9f8365e --- /dev/null +++ b/src/util/util/Database.ts
@@ -0,0 +1,107 @@ +import { config } from "dotenv"; +import fs from "fs"; +import path from "path"; +import { green, red, yellow } from "picocolors"; +import { exit } from "process"; +import "reflect-metadata"; +import { DataSource, DataSourceOptions, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import * as Models from "../entities"; +import { BaseClass, BaseClassWithoutId } from "../entities"; + +// UUID extension option is only supported with postgres +// We want to generate all id's with Snowflakes that's why we have our own BaseEntity class + +let promise: Promise<any>; +let dataSource: DataSource; + +export async function getOrInitialiseDatabase(): Promise<DataSource> { + //if (dataSource) return dataSource; // prevent initalizing multiple times + + if (dataSource.isInitialized) return dataSource; + + await dataSource.initialize(); + console.log(`[Database] ${green("Connected!")}`); + await dataSource.runMigrations(); + console.log(`[Database] ${green("Up to date!")}`); + + if ("DB_MIGRATE" in process.env) { + console.log("DB_MIGRATE specified, exiting!"); + exit(0); + } + return dataSource; +} + +export function closeDatabase() { + dataSource?.destroy(); +} + +function getDataSourceOptions(): DataSourceOptions { + config(); + //get connection string and check for migrations + const dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db"); + const type = dbConnectionString.includes("://") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : ("sqlite" as any); + const isSqlite = type.includes("sqlite"); + const migrationsExist = fs.existsSync(path.join(__dirname, "..", "migrations", type)); + //read env vars + const synchronizeInsteadOfMigrations = "DB_UNSAFE" in process.env; + const verboseDb = "DB_VERBOSE" in process.env; + + if (isSqlite) + console.log(`[Database] ${red(`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`)}`); + if (verboseDb) + console.log( + `[Database] ${red(`Verbose database logging is enabled, this might impact performance! Unset DB_VERBOSE to disable.`)}` + ); + + if (synchronizeInsteadOfMigrations) { + console.log( + `[Database] ${red( + `Unsafe database upgrades are enabled! We are not responsible for broken databases! Unset DB_UNSAFE to disable.` + )}` + ); + } else if (!migrationsExist) { + console.log(`[Database] ${red(`Database engine not supported! Set UNSAFE_DB to bypass.`)}`); + console.log(`[Database] ${red(`Please mention this to Fosscord developers, and provide this info:`)}`); + console.log( + `[Database]\n${red( + JSON.stringify( + { + db_type: type, + migrations_exist: migrationsExist + }, + null, + 4 + ) + )}` + ); + + if (!("DB_MIGRATE" in process.env)) exit(1); + } + console.log(`[Database] ${yellow(`Configuring data source to use ${type} database...`)}`); + return { + type, + charset: "utf8mb4", + url: isSqlite ? undefined : dbConnectionString, + database: isSqlite ? dbConnectionString : undefined, + // @ts-ignore + //entities: Object.values(Models).filter((x) => x.constructor.name !== "Object" && x.constructor.name !== "Array" && x.constructor.name !== "BigInt" && x).map(x=>x.name), + entities: Object.values(Models).filter((x) => x.constructor.name == "Function" && shouldIncludeEntity(x.name)), + synchronize: synchronizeInsteadOfMigrations, + logging: verboseDb ? "all" : false, + cache: { + duration: 1000 * 3 // cache all find queries for 3 seconds + }, + bigNumberStrings: false, + supportBigNumbers: true, + name: "default", + migrations: synchronizeInsteadOfMigrations ? [] : [path.join(__dirname, "..", "migrations", type, "*.js")], + migrationsRun: !synchronizeInsteadOfMigrations, + applicationName: `Fosscord Server`, + } as DataSourceOptions; +} + +function shouldIncludeEntity(name: string): boolean { + return ![BaseClassWithoutId, PrimaryColumn, BaseClass, PrimaryGeneratedColumn].map((x) => x.name).includes(name); +} + +export default dataSource = new DataSource(getDataSourceOptions()); diff --git a/util/src/util/Email.ts b/src/util/util/Email.ts
index 6885da33..c98ccff0 100644 --- a/util/src/util/Email.ts +++ b/src/util/util/Email.ts
@@ -15,7 +15,7 @@ export function adjustEmail(email?: string): string | undefined { // replace .dots and +alternatives -> Gmail Dot Trick https://support.google.com/mail/answer/7436150 and https://generator.email/blog/gmail-generator let v = user.replace(/[.]|(\+.*)/g, "") + "@gmail.com"; } - + if (domain === "google.com") { // replace .dots and +alternatives -> Google Staff GMail Dot Trick let v = user.replace(/[.]|(\+.*)/g, "") + "@google.com"; diff --git a/util/src/util/Event.ts b/src/util/util/Event.ts
index bb624051..383e4e50 100644 --- a/util/src/util/Event.ts +++ b/src/util/util/Event.ts
@@ -1,7 +1,7 @@ import { Channel } from "amqplib"; -import { RabbitMQ } from "./RabbitMQ"; import EventEmitter from "events"; import { EVENT, Event } from "../interfaces"; +import { RabbitMQ } from "./RabbitMQ"; export const events = new EventEmitter(); export async function emitEvent(payload: Omit<Event, "created_at">) { @@ -58,8 +58,8 @@ export async function listenEvent(event: string, callback: (event: EventOpts) => process.setMaxListeners(process.getMaxListeners() - 1); }; - const listener = (msg: ProcessEvent) => { - msg.type === "event" && msg.id === event && callback({ ...msg.event, cancel }); + const listener = (message: any) => { + message.type === "event" && message.id === event && callback({ ...message.event, cancel }); }; process.addListener("message", listener); @@ -79,12 +79,7 @@ export async function listenEvent(event: string, callback: (event: EventOpts) => } } -async function rabbitListen( - channel: Channel, - id: string, - callback: (event: EventOpts) => any, - opts?: { acknowledge?: boolean } -) { +async function rabbitListen(channel: Channel, id: string, callback: (event: EventOpts) => any, opts?: { acknowledge?: boolean }) { await channel.assertExchange(id, "fanout", { durable: false }); const q = await channel.assertQueue("", { exclusive: true, autoDelete: true }); @@ -109,12 +104,12 @@ async function rabbitListen( channel.ack(opts); }, channel, - cancel, + cancel }); // rabbitCh.ack(opts); }, { - noAck: !opts?.acknowledge, + noAck: !opts?.acknowledge } ); diff --git a/util/src/util/FieldError.ts b/src/util/util/FieldError.ts
index 406b33e8..bdffd618 100644 --- a/util/src/util/FieldError.ts +++ b/src/util/util/FieldError.ts
@@ -1,5 +1,3 @@ -import "missing-native-js-functions"; - export function FieldErrors(fields: Record<string, { code?: string; message: string }>) { return new FieldError( 50035, @@ -8,9 +6,9 @@ export function FieldErrors(fields: Record<string, { code?: string; message: str _errors: [ { message, - code: code || "BASE_TYPE_INVALID", - }, - ], + code: code || "BASE_TYPE_INVALID" + } + ] })) ); } diff --git a/util/src/util/Intents.ts b/src/util/util/Intents.ts
index 1e840b76..db4c9e28 100644 --- a/util/src/util/Intents.ts +++ b/src/util/util/Intents.ts
@@ -22,13 +22,12 @@ export class Intents extends BitField { GUILD_POLICY_EXECUTION: BigInt(1) << BigInt(21), // guild policy execution LIVE_MESSAGE_COMPOSITION: BigInt(1) << BigInt(32), // allow composing messages using the gateway GUILD_ROUTES: BigInt(1) << BigInt(41), // message routes affecting the guild - DIRECT_MESSAGES_THREADS: BigInt(1) << BigInt(42), // direct message threads + DIRECT_MESSAGES_THREADS: BigInt(1) << BigInt(42), // direct message threads JUMBO_EVENTS: BigInt(1) << BigInt(43), // jumbo events (size limits to be defined later) LOBBIES: BigInt(1) << BigInt(44), // lobbies - INSTANCE_ROUTES: BigInt(1) << BigInt(60), // all message route changes + INSTANCE_ROUTES: BigInt(1) << BigInt(60), // all message route changes INSTANCE_GUILD_CHANGES: BigInt(1) << BigInt(61), // all guild create, guild object patch, split, merge and delete events INSTANCE_POLICY_UPDATES: BigInt(1) << BigInt(62), // all instance policy updates INSTANCE_USER_UPDATES: BigInt(1) << BigInt(63) // all instance user updates }; } - diff --git a/src/util/util/InvisibleCharacters.ts b/src/util/util/InvisibleCharacters.ts new file mode 100644
index 00000000..9bffec58 --- /dev/null +++ b/src/util/util/InvisibleCharacters.ts
@@ -0,0 +1,57 @@ +// List from https://invisible-characters.com/ +export const InvisibleCharacters = [ + "\u{9}", //Tab + "\u{c}", //Form feed + //'\u{20}', //Space //categories can have spaces in them + "\u{ad}", //Soft hyphen + // '\u{34f}', //Combining grapheme joiner + "\u{61c}", //Arabic letter mark + "\u{115f}", //Hangul choseong filler + "\u{1160}", //Hangul jungseong filler + "\u{17b4}", //Khmer vowel inherent AQ + "\u{17b5}", //Khmer vowel inherent AA + "\u{180e}", //Mongolian vowel separator + "\u{2000}", //En quad + "\u{2001}", //Em quad + "\u{2002}", //En space + "\u{2003}", //Em space + "\u{2004}", //Three-per-em space + "\u{2005}", //Four-per-em space + "\u{2006}", //Six-per-em space + "\u{2007}", //Figure space + "\u{2008}", //Punctuation space + "\u{2009}", //Thin space + "\u{200a}", //Hair space + "\u{200b}", //Zero width space + "\u{200c}", //Zero width non-joiner + // '\u{200d}', //Zero width joiner + "\u{200e}", //Left-to-right mark + "\u{200f}", //Right-to-left mark + "\u{202f}", //Narrow no-break space + "\u{205f}", //Medium mathematical space + // '\u{2060}', //Word joiner -- WJ is required in some languages that don't use spaces to split words + "\u{2061}", //Function application + "\u{2062}", //Invisible times + "\u{2063}", //Invisible separator + "\u{2064}", //Invisible plus + "\u{206a}", //Inhibit symmetric swapping + "\u{206b}", //Activate symmetric swapping + "\u{206c}", //Inhibit arabic form shaping + "\u{206d}", //Activate arabic form shaping + "\u{206e}", //National digit shapes + "\u{206f}", //Nominal digit shapes + "\u{3000}", //Ideographic space + "\u{2800}", //Braille pattern blank + "\u{3164}", //Hangul filler + "\u{feff}", //Zero width no-break space + "\u{ffa0}", //Haldwidth hangul filler + "\u{1d159}", //Musical symbol null notehead + "\u{1d173}", //Musical symbol begin beam + "\u{1d174}", //Musical symbol end beam + "\u{1d175}", //Musical symbol begin tie + "\u{1d176}", //Musical symbol end tie + "\u{1d177}", //Musical symbol begin slur + "\u{1d178}", //Musical symbol end slur + "\u{1d179}", //Musical symbol begin phrase + "\u{1d17a}" //Musical symbol end phrase +]; diff --git a/src/util/util/MFA.ts b/src/util/util/MFA.ts new file mode 100644
index 00000000..b9af6d23 --- /dev/null +++ b/src/util/util/MFA.ts
@@ -0,0 +1,18 @@ +import crypto from "crypto"; +import { Config } from "."; +import { BackupCode } from "../entities/BackupCodes"; + +export function generateMfaBackupCodes(user_id: string) { + let backup_codes: BackupCode[] = []; + for (let i = 0; i < Config.get().security.mfaBackupCodeCount; i++) { + const code = BackupCode.create({ + user: { id: user_id }, + code: crypto.randomBytes(Config.get().security.mfaBackupCodeBytes).toString("hex"), // 8 characters + consumed: false, + expired: false + }); + backup_codes.push(code); + } + + return backup_codes; +} diff --git a/util/src/util/MessageFlags.ts b/src/util/util/MessageFlags.ts
index b59295c4..c5d5d02a 100644 --- a/util/src/util/MessageFlags.ts +++ b/src/util/util/MessageFlags.ts
@@ -15,6 +15,6 @@ export class MessageFlags extends BitField { INTERACTION_WAIT: BigInt(1) << BigInt(7), // discord.com calls this LOADING // FAILED_TO_MENTION_SOME_ROLES_IN_THREAD: BigInt(1) << BigInt(8) SCRIPT_WAIT: BigInt(1) << BigInt(24), // waiting for the self command to complete - IMPORT_WAIT: BigInt(1) << BigInt(25), // latest message of a bulk import, waiting for the rest of the channel to be backfilled + IMPORT_WAIT: BigInt(1) << BigInt(25) // latest message of a bulk import, waiting for the rest of the channel to be backfilled }; } diff --git a/util/src/util/Permissions.ts b/src/util/util/Permissions.ts
index e5459ab5..b8d0d8ae 100644 --- a/util/src/util/Permissions.ts +++ b/src/util/util/Permissions.ts
@@ -1,17 +1,8 @@ // https://github.com/discordjs/discord.js/blob/master/src/util/Permissions.js // Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah +import { HTTPError } from ".."; import { Channel, ChannelPermissionOverwrite, Guild, Member, Role } from "../entities"; -import { BitField } from "./BitField"; -import "missing-native-js-functions"; -import { BitFieldResolvable, BitFlag } from "./BitField"; - -var HTTPError: any; - -try { - HTTPError = require("lambert-server").HTTPError; -} catch (e) { - HTTPError = Error; -} +import { BitField, BitFieldResolvable, BitFlag } from "./BitField"; export type PermissionResolvable = bigint | number | Permissions | PermissionResolvable[] | PermissionString; @@ -68,7 +59,7 @@ export class Permissions extends BitField { MANAGE_THREADS: BitFlag(34), USE_PUBLIC_THREADS: BitFlag(35), USE_PRIVATE_THREADS: BitFlag(36), - USE_EXTERNAL_STICKERS: BitFlag(37), + USE_EXTERNAL_STICKERS: BitFlag(37) /** * CUSTOM PERMISSIONS ideas: @@ -132,7 +123,7 @@ export class Permissions extends BitField { static finalPermission({ user, guild, - channel, + channel }: { user: { id: string; roles: string[] }; guild: { roles: Role[] }; @@ -172,7 +163,7 @@ export class Permissions extends BitField { "USE_EXTERNAL_EMOJIS", "CONNECT", "SPEAK", - "MANAGE_CHANNELS", + "MANAGE_CHANNELS" ]); } @@ -207,9 +198,9 @@ export async function getPermission( } = {} ) { if (!user_id) throw new HTTPError("User not found"); - var channel: Channel | undefined; - var member: Member | undefined; - var guild: Guild | undefined; + let channel: Channel | undefined; + let member: Member | undefined; + let guild: Guild | undefined; if (channel_id) { channel = await Channel.findOneOrFail({ @@ -222,8 +213,8 @@ export async function getPermission( "owner_id", "guild_id", // @ts-ignore - ...(opts.channel_select || []), - ], + ...(opts.channel_select || []) + ] }); if (channel.guild_id) guild_id = channel.guild_id; // derive guild_id from the channel } @@ -235,9 +226,9 @@ export async function getPermission( "id", "owner_id", // @ts-ignore - ...(opts.guild_select || []), + ...(opts.guild_select || []) ], - relations: opts.guild_relations, + relations: opts.guild_relations }); if (guild.owner_id === user_id) return new Permissions(Permissions.FLAGS.ADMINISTRATOR); @@ -247,9 +238,10 @@ export async function getPermission( select: [ "id", "roles", + "index", // @ts-ignore - ...(opts.member_select || []), - ], + ...(opts.member_select || []) + ] }); } @@ -257,19 +249,19 @@ export async function getPermission( if (!recipient_ids?.length) recipient_ids = null; // TODO: remove guild.roles and convert recipient_ids to recipients - var permission = Permissions.finalPermission({ + let permission = Permissions.finalPermission({ user: { id: user_id, - roles: member?.roles.map((x) => x.id) || [], + roles: member?.roles.map((x) => x.id) || [] }, guild: { - roles: member?.roles || [], + roles: member?.roles || [] }, channel: { overwrites: channel?.permission_overwrites, owner_id: channel?.owner_id, - recipient_ids, - }, + recipient_ids + } }); const obj = new Permissions(permission); diff --git a/util/src/util/RabbitMQ.ts b/src/util/util/RabbitMQ.ts
index 0f5eb6aa..638b805b 100644 --- a/util/src/util/RabbitMQ.ts +++ b/src/util/util/RabbitMQ.ts
@@ -1,4 +1,4 @@ -import amqp, { Connection, Channel } from "amqplib"; +import { Channel, Connection } from "amqplib"; // import Config from "./Config"; export const RabbitMQ: { connection: Connection | null; channel: Channel | null; init: () => Promise<void> } = { @@ -15,5 +15,5 @@ export const RabbitMQ: { connection: Connection | null; channel: Channel | null; // console.log(`[RabbitMQ] connected`); // this.channel = await this.connection.createChannel(); // console.log(`[RabbitMQ] channel created`); - }, + } }; diff --git a/util/src/util/Regex.ts b/src/util/util/Regex.ts
index 83fc9fe8..83fc9fe8 100644 --- a/util/src/util/Regex.ts +++ b/src/util/util/Regex.ts
diff --git a/util/src/util/Rights.ts b/src/util/util/Rights.ts
index b28c75b7..51bb098c 100644 --- a/util/src/util/Rights.ts +++ b/src/util/util/Rights.ts
@@ -1,15 +1,6 @@ -import { BitField } from "./BitField"; -import "missing-native-js-functions"; -import { BitFieldResolvable, BitFlag } from "./BitField"; +import { HTTPError } from ".."; import { User } from "../entities"; - -var HTTPError: any; - -try { - HTTPError = require("lambert-server").HTTPError; -} catch (e) { - HTTPError = Error; -} +import { BitField, BitFieldResolvable, BitFlag } from "./BitField"; export type RightResolvable = bigint | number | Rights | RightResolvable[] | RightString; @@ -60,7 +51,7 @@ export class Rights extends BitField { CREDITABLE: BitFlag(32), // can receive money from monetisation related features KICK_BAN_MEMBERS: BitFlag(33), // can kick or ban guild or group DM members in the guilds/groups that they have KICK_MEMBERS, or BAN_MEMBERS - SELF_LEAVE_GROUPS: BitFlag(34), + SELF_LEAVE_GROUPS: BitFlag(34), // can leave the guilds or group DMs that they joined on their own (one can always leave a guild or group DMs they have been force-added) PRESENCE: BitFlag(35), // inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user @@ -88,15 +79,16 @@ export class Rights extends BitField { // @ts-ignore throw new HTTPError(`You are missing the following rights ${permission}`, 403); } - } const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0)); -export async function getRights( user_id: string +export async function getRights( + user_id: string /**, opts: { in_behalf?: (keyof User)[]; - } = {} **/) { + } = {} **/ +) { let user = await User.findOneOrFail({ where: { id: user_id } }); return new Rights(user.rights); -} +} diff --git a/util/src/util/Snowflake.ts b/src/util/util/Snowflake.ts
index 134d526e..89f4f0c3 100644 --- a/util/src/util/Snowflake.ts +++ b/src/util/util/Snowflake.ts
@@ -83,14 +83,15 @@ export class Snowflake { return dec; } - static generateWorkerProcess() { // worker process - returns a number - var time = BigInt(Date.now() - Snowflake.EPOCH) << BigInt(22); - var worker = Snowflake.workerId << 17n; - var process = Snowflake.processId << 12n; - var increment = Snowflake.INCREMENT++; + static generateWorkerProcess() { + // worker process - returns a number + let time = BigInt(Date.now() - Snowflake.EPOCH) << BigInt(22); + let worker = Snowflake.workerId << 17n; + let process = Snowflake.processId << 12n; + let increment = Snowflake.INCREMENT++; return BigInt(time | worker | process | increment); } - + static generate() { return Snowflake.generateWorkerProcess().toString(); } @@ -117,13 +118,13 @@ export class Snowflake { workerID: parseInt(BINARY.substring(42, 47), 2), processID: parseInt(BINARY.substring(47, 52), 2), increment: parseInt(BINARY.substring(52, 64), 2), - binary: BINARY, + binary: BINARY }; Object.defineProperty(res, "date", { get: function get() { return new Date(this.timestamp); }, - enumerable: true, + enumerable: true }); return res; } diff --git a/util/src/util/String.ts b/src/util/util/String.ts
index 55f11e8d..55f11e8d 100644 --- a/util/src/util/String.ts +++ b/src/util/util/String.ts
diff --git a/util/src/util/Token.ts b/src/util/util/Token.ts
index 500ace45..d192a13a 100644 --- a/util/src/util/Token.ts +++ b/src/util/util/Token.ts
@@ -1,6 +1,6 @@ import jwt, { VerifyOptions } from "jsonwebtoken"; -import { Config } from "./Config"; import { User } from "../entities"; +import { Config } from "./Config"; export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; @@ -11,18 +11,17 @@ export function checkToken(token: string, jwtSecret: string): Promise<any> { in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix, as we don't really have separate pathways for bots **/ - + jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => { if (err || !decoded) return rej("Invalid Token"); - const user = await User.findOne( - { id: decoded.id }, - { select: ["data", "bot", "disabled", "deleted", "rights"] } - ); + const user = await User.findOne({ + where: { id: decoded.id }, + select: ["data", "bot", "disabled", "deleted", "rights"] + }); if (!user) return rej("Invalid Token"); // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds - if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) - return rej("Invalid Token"); + if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) return rej("Invalid Token"); if (user.disabled) return rej("User disabled"); if (user.deleted) return rej("User not found"); @@ -40,7 +39,7 @@ export async function generateToken(id: string) { { id: id, iat }, Config.get().security.jwtSecret, { - algorithm, + algorithm }, (err, token) => { if (err) return rej(err); diff --git a/util/src/util/TraverseDirectory.ts b/src/util/util/TraverseDirectory.ts
index 3d0d6279..6f60e73b 100644 --- a/util/src/util/TraverseDirectory.ts +++ b/src/util/util/TraverseDirectory.ts
@@ -1,13 +1,10 @@ import { Server, traverseDirectory } from "lambert-server"; //if we're using ts-node, use ts files instead of js -const extension = Symbol.for("ts-node.register.instance") in process ? "ts" : "js" +const extension = Symbol.for("ts-node.register.instance") in process ? "ts" : "js"; -const DEFAULT_FILTER = new RegExp("^([^\.].*)(?<!\.d)\.(" + extension + ")$"); +const DEFAULT_FILTER = new RegExp("^([^.].*)(?<!.d).(" + extension + ")$"); export function registerRoutes(server: Server, root: string) { - return traverseDirectory( - { dirname: root, recursive: true, filter: DEFAULT_FILTER }, - server.registerRoute.bind(server, root) - ); + return traverseDirectory({ dirname: root, recursive: true, filter: DEFAULT_FILTER }, server.registerRoute.bind(server, root)); } diff --git a/util/src/util/cdn.ts b/src/util/util/cdn.ts
index ea950cd1..5573b848 100644 --- a/util/src/util/cdn.ts +++ b/src/util/util/cdn.ts
@@ -1,8 +1,7 @@ import FormData from "form-data"; -import { HTTPError } from "lambert-server"; import fetch from "node-fetch"; +import { HTTPError } from ".."; import { Config } from "./Config"; -import multer from "multer"; export async function uploadFile(path: string, file?: Express.Multer.File) { if (!file?.buffer) throw new HTTPError("Missing file in body"); @@ -10,16 +9,16 @@ export async function uploadFile(path: string, file?: Express.Multer.File) { const form = new FormData(); form.append("file", file.buffer, { contentType: file.mimetype, - filename: file.originalname, + filename: file.originalname }); const response = await fetch(`${Config.get().cdn.endpointPrivate || "http://localhost:3003"}${path}`, { headers: { signature: Config.get().security.requestSignature, - ...form.getHeaders(), + ...form.getHeaders() }, method: "POST", - body: form, + body: form }); const result = await response.json(); @@ -45,9 +44,9 @@ export async function handleFile(path: string, body?: string): Promise<string | export async function deleteFile(path: string) { const response = await fetch(`${Config.get().cdn.endpointPrivate || "http://localhost:3003"}${path}`, { headers: { - signature: Config.get().security.requestSignature, + signature: Config.get().security.requestSignature }, - method: "DELETE", + method: "DELETE" }); const result = await response.json(); diff --git a/src/util/util/imports/Checks.ts b/src/util/util/imports/Checks.ts new file mode 100644
index 00000000..bd3c6343 --- /dev/null +++ b/src/util/util/imports/Checks.ts
@@ -0,0 +1,121 @@ +//source: https://github.com/Flam3rboy/-server/blob/master/src/check.ts +import { NextFunction, Request, Response } from "express"; +import { HTTPError } from "."; + +const OPTIONAL_PREFIX = "$"; +const EMAIL_REGEX = + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + +export function check(schema: any) { + return (req: Request, res: Response, next: NextFunction) => { + try { + const result = instanceOf(schema, req.body, { path: "body" }); + if (result === true) return next(); + throw result; + } catch (error) { + next(new HTTPError((error as any).toString(), 400)); + } + }; +} +export class Tuple { + public types: any[]; + constructor(...types: any[]) { + this.types = types; + } +} + +export class Email { + constructor(public email: string) {} + check() { + return !!this.email.match(EMAIL_REGEX); + } +} +export function instanceOf(type: any, value: any, { path = "", optional = false }: { path?: string; optional?: boolean } = {}): boolean { + if (!type) return true; // no type was specified + + if (value == null) { + if (optional) return true; + throw `${path} is required`; + } + + switch (type) { + case String: + if (typeof value === "string") return true; + throw `${path} must be a string`; + case Number: + value = Number(value); + if (typeof value === "number" && !isNaN(value)) return true; + throw `${path} must be a number`; + case BigInt: + try { + value = BigInt(value); + if (typeof value === "bigint") return true; + } catch (error) {} + throw `${path} must be a bigint`; + case Boolean: + if (value == "true") value = true; + if (value == "false") value = false; + if (typeof value === "boolean") return true; + throw `${path} must be a boolean`; + case Object: + if (typeof value === "object" && value !== null) return true; + throw `${path} must be a object`; + } + + if (typeof type === "object") { + if (Array.isArray(type)) { + if (!Array.isArray(value)) throw `${path} must be an array`; + if (!type.length) return true; // type array didn't specify any type + + return value.every((val, i) => instanceOf(type[0], val, { path: `${path}[${i}]`, optional })); + } + if (type?.constructor?.name != "Object") { + if (type instanceof Tuple) { + if ( + (<Tuple>type).types.some((x) => { + try { + return instanceOf(x, value, { path, optional }); + } catch (error) { + return false; + } + }) + ) { + return true; + } + throw `${path} must be one of ${type.types}`; + } + if (type instanceof Email) { + if ((<Email>type).check()) return true; + throw `${path} is not a valid E-Mail`; + } + if (value instanceof type) return true; + throw `${path} must be an instance of ${type}`; + } + if (typeof value !== "object") throw `${path} must be a object`; + + const diff = Object.keys(value).missing( + Object.keys(type).map((x) => (x.startsWith(OPTIONAL_PREFIX) ? x.slice(OPTIONAL_PREFIX.length) : x)) + ); + + if (diff.length) throw `Unkown key ${diff}`; + + return Object.keys(type).every((key) => { + let newKey = key; + const OPTIONAL = key.startsWith(OPTIONAL_PREFIX); + if (OPTIONAL) newKey = newKey.slice(OPTIONAL_PREFIX.length); + + return instanceOf(type[key], value[newKey], { + path: `${path}.${newKey}`, + optional: OPTIONAL + }); + }); + } else if (typeof type === "number" || typeof type === "string" || typeof type === "boolean") { + if (value === type) return true; + throw `${path} must be ${value}`; + } else if (typeof type === "bigint") { + if (BigInt(value) === type) return true; + throw `${path} must be ${value}`; + } + + return type == value; +} diff --git a/src/util/util/imports/HTTPError.ts b/src/util/util/imports/HTTPError.ts new file mode 100644
index 00000000..70ba92a8 --- /dev/null +++ b/src/util/util/imports/HTTPError.ts
@@ -0,0 +1,5 @@ +export class HTTPError extends Error { + constructor(message: string, public code: number = 400) { + super(message); + } +} diff --git a/src/util/util/imports/OrmUtils.ts b/src/util/util/imports/OrmUtils.ts new file mode 100644
index 00000000..0556994b --- /dev/null +++ b/src/util/util/imports/OrmUtils.ts
@@ -0,0 +1,96 @@ +//source: https://github.com/typeorm/typeorm/blob/master/src/util/OrmUtils.ts +export class OrmUtils { + // Checks if it's an object made by Object.create(null), {} or new Object() + private static isPlainObject(item: any) { + if (item === null || item === undefined) { + return false; + } + + return !item.constructor || item.constructor === Object; + } + + private static mergeArrayKey(target: any, key: number, value: any, memo: Map<any, any>) { + // Have we seen this before? Prevent infinite recursion. + if (memo.has(value)) { + target[key] = memo.get(value); + return; + } + + if (value instanceof Promise) { + // Skip promises entirely. + // This is a hold-over from the old code & is because we don't want to pull in + // the lazy fields. Ideally we'd remove these promises via another function first + // but for now we have to do it here. + return; + } + + if (!this.isPlainObject(value) && !Array.isArray(value)) { + target[key] = value; + return; + } + + if (!target[key]) { + target[key] = Array.isArray(value) ? [] : {}; + } + + memo.set(value, target[key]); + this.merge(target[key], value, memo); + memo.delete(value); + } + + private static mergeObjectKey(target: any, key: string, value: any, memo: Map<any, any>) { + // Have we seen this before? Prevent infinite recursion. + if (memo.has(value)) { + Object.assign(target, { [key]: memo.get(value) }); + return; + } + + if (value instanceof Promise) { + // Skip promises entirely. + // This is a hold-over from the old code & is because we don't want to pull in + // the lazy fields. Ideally we'd remove these promises via another function first + // but for now we have to do it here. + return; + } + + if (!this.isPlainObject(value) && !Array.isArray(value)) { + Object.assign(target, { [key]: value }); + return; + } + + if (!target[key]) { + Object.assign(target, { [key]: value }); + } + + memo.set(value, target[key]); + this.merge(target[key], value, memo); + memo.delete(value); + } + + private static merge(target: any, source: any, memo: Map<any, any> = new Map()): any { + if (Array.isArray(target) && Array.isArray(source)) { + for (let key = 0; key < source.length; key++) { + this.mergeArrayKey(target, key, source[key], memo); + } + } else { + for (const key of Object.keys(source)) { + this.mergeObjectKey(target, key, source[key], memo); + } + } + } + + /** + * Deep Object.assign. + */ + static mergeDeep(target: any, ...sources: any[]): any { + if (!sources.length) { + return target; + } + + for (const source of sources) { + OrmUtils.merge(target, source); + } + + return target; + } +} diff --git a/src/util/util/imports/index.ts b/src/util/util/imports/index.ts new file mode 100644
index 00000000..120cff11 --- /dev/null +++ b/src/util/util/imports/index.ts
@@ -0,0 +1,3 @@ +export * from "./Checks"; +export * from "./HTTPError"; +export * from "./OrmUtils"; diff --git a/util/src/util/index.ts b/src/util/util/index.ts
index f7a273cb..11f0b72a 100644 --- a/util/src/util/index.ts +++ b/src/util/util/index.ts
@@ -1,6 +1,6 @@ export * from "./ApiError"; +export * from "./Array"; export * from "./BitField"; -export * from "./Token"; //export * from "./Categories"; export * from "./cdn"; export * from "./Config"; @@ -9,7 +9,11 @@ export * from "./Database"; export * from "./Email"; export * from "./Event"; export * from "./FieldError"; +export * from "./imports/HTTPError"; +export * from "./imports/index"; +export * from "./imports/OrmUtils"; export * from "./Intents"; +export * from "./InvisibleCharacters"; export * from "./MessageFlags"; export * from "./Permissions"; export * from "./RabbitMQ"; @@ -17,6 +21,5 @@ export * from "./Regex"; export * from "./Rights"; export * from "./Snowflake"; export * from "./String"; -export * from "./Array"; +export * from "./Token"; export * from "./TraverseDirectory"; -export * from "./InvisibleCharacters"; \ No newline at end of file