Remove mariadb support as it isnt maintained and hasnt worked in over a year

This commit is contained in:
Rory& 2025-09-30 05:23:53 +02:00
parent b87d28c2c9
commit d5d719f3c8
72 changed files with 7 additions and 751 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@ -69,8 +69,8 @@
"husky": "^9.1.7",
"prettier": "^3.6.2",
"pretty-quick": "^4.2.2",
"typescript": "^5.9.2",
"ts-node": "^10.9.2"
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.899.0",
@ -126,7 +126,6 @@
"@yukikaze-bot/erlpack": "^1.0.1",
"jimp": "^1.6.0",
"mailgun.js": "^12.1.0",
"mysql": "^2.18.1",
"node-mailjet": "^6.0.9",
"nodemailer": "^7.0.6",
"pg": "^8.16.3",

View File

@ -27,12 +27,10 @@ import {
import { BaseClass } from "./BaseClass";
import { Team } from "./Team";
import { User } from "./User";
import { dbEngine } from "../util/Database";
import { Guild } from "./Guild";
@Entity({
name: "applications",
engine: dbEngine,
})
export class Application extends BaseClass {
@Column()

View File

@ -27,7 +27,6 @@ import {
import { URL } from "url";
import { deleteFile } from "../util/cdn";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
import {
getUrlSignature,
NewUrlUserSignatureData,
@ -36,7 +35,6 @@ import {
@Entity({
name: "attachments",
engine: dbEngine,
})
export class Attachment extends BaseClass {
@Column()

View File

@ -20,7 +20,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { ChannelPermissionOverwrite } from "./Channel";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum AuditLogEvents {
// guild level
@ -114,7 +113,6 @@ export enum AuditLogEvents {
@Entity({
name: "audit_logs",
engine: dbEngine,
})
export class AuditLog extends BaseClass {
@JoinColumn({ name: "target_id" })

View File

@ -16,7 +16,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { dbEngine } from "@spacebar/util";
import { BaseClass } from "./BaseClass";
import { Entity, JoinColumn, ManyToOne, Column } from "typeorm";
import { User } from "./User";
@ -41,7 +40,6 @@ export class AutomodCustomWordsRule {
@Entity({
name: "automod_rules",
engine: dbEngine,
})
export class AutomodRule extends BaseClass {
@JoinColumn({ name: "creator_id" })

View File

@ -20,11 +20,9 @@ import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import crypto from "crypto";
import { dbEngine } from "../util/Database";
@Entity({
name: "backup_codes",
engine: dbEngine,
})
export class BackupCode extends BaseClass {
@JoinColumn({ name: "user_id" })

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClassWithoutId } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "badges",
engine: dbEngine,
})
export class Badge extends BaseClassWithoutId {
@Column({ primary: true })

View File

@ -20,11 +20,9 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { User } from "./User";
import { dbEngine } from "../util/Database";
@Entity({
name: "bans",
engine: dbEngine,
})
export class Ban extends BaseClass {
@Column({ nullable: true })

View File

@ -18,7 +18,6 @@
import { Column, Entity } from "typeorm";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import { dbEngine } from "../util/Database";
// TODO: categories:
// [{
@ -36,7 +35,6 @@ import { dbEngine } from "../util/Database";
@Entity({
name: "categories",
engine: dbEngine,
})
export class Categories extends BaseClassWithoutId {
// Not using snowflake

View File

@ -37,7 +37,6 @@ import { Recipient } from "./Recipient";
import { PublicUserProjection, User } from "./User";
import { VoiceState } from "./VoiceState";
import { Webhook } from "./Webhook";
import { dbEngine } from "../util/Database";
import { Member } from "./Member";
export enum ChannelType {
@ -66,7 +65,6 @@ export enum ChannelType {
@Entity({
name: "channels",
engine: dbEngine,
})
export class Channel extends BaseClass {
@Column()

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "client_release",
engine: dbEngine,
})
export class ClientRelease extends BaseClass {
@Column()

View File

@ -18,13 +18,11 @@
import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
import { User } from "./User";
import { Channel } from "./Channel";
@Entity({
name: "cloud_attachments",
engine: dbEngine,
})
export class CloudAttachment extends BaseClass {
// Internal tracking metadata

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "config",
engine: dbEngine,
})
export class ConfigEntity extends BaseClassWithoutId {
@PrimaryIdColumn()

View File

@ -20,7 +20,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { ConnectedAccountTokenData } from "../interfaces";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export type PublicConnectedAccount = Pick<
ConnectedAccount,
@ -29,7 +28,6 @@ export type PublicConnectedAccount = Pick<
@Entity({
name: "connected_accounts",
engine: dbEngine,
})
export class ConnectedAccount extends BaseClass {
@Column()

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "connection_config",
engine: dbEngine,
})
export class ConnectionConfigEntity extends BaseClassWithoutId {
@PrimaryIdColumn()

View File

@ -19,11 +19,9 @@
import { BaseClass } from "./BaseClass";
import { Entity, Column } from "typeorm";
import { Embed } from "./Message";
import { dbEngine } from "../util/Database";
@Entity({
name: "embed_cache",
engine: dbEngine,
})
export class EmbedCache extends BaseClass {
@Column()

View File

@ -20,11 +20,9 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { User } from ".";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { dbEngine } from "../util/Database";
@Entity({
name: "emojis",
engine: dbEngine,
})
export class Emoji extends BaseClass {
@Column()

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "security_settings",
engine: dbEngine,
})
export class SecuritySettings extends BaseClass {
@Column({ nullable: true })

View File

@ -30,7 +30,6 @@ import { Template } from "./Template";
import { User } from "./User";
import { VoiceState } from "./VoiceState";
import { Webhook } from "./Webhook";
import { dbEngine } from "../util/Database";
// TODO: application_command_count, application_command_counts: {1: 0, 2: 0, 3: 0}
// TODO: guild_scheduled_events
@ -62,7 +61,6 @@ export const PublicGuildRelations = [
@Entity({
name: "guilds",
engine: dbEngine,
})
export class Guild extends BaseClass {
@Column({ type: String, nullable: true })

View File

@ -22,13 +22,11 @@ import { Channel } from "./Channel";
import { Guild } from "./Guild";
import { Member } from "./Member";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export const PublicInviteRelation = ["inviter", "guild", "channel"];
@Entity({
name: "invites",
engine: dbEngine,
})
export class Invite extends BaseClassWithoutId {
@PrimaryIdColumn()

View File

@ -48,7 +48,6 @@ import { Guild } from "./Guild";
import { Message } from "./Message";
import { Role } from "./Role";
import { PublicUser, User } from "./User";
import { dbEngine } from "../util/Database";
export const MemberPrivateProjection: (keyof Member)[] = [
"id",
@ -68,7 +67,6 @@ export const MemberPrivateProjection: (keyof Member)[] = [
@Entity({
name: "members",
engine: dbEngine,
})
@Index(["id", "guild_id"], { unique: true })
export class Member extends BaseClassWithoutId {

View File

@ -39,7 +39,6 @@ import { Guild } from "./Guild";
import { Webhook } from "./Webhook";
import { Sticker } from "./Sticker";
import { Attachment } from "./Attachment";
import { dbEngine } from "../util/Database";
import { NewUrlUserSignatureData } from "../Signing";
export enum MessageType {
@ -72,7 +71,6 @@ export enum MessageType {
@Entity({
name: "messages",
engine: dbEngine,
})
@Index(["channel_id", "id"], { unique: true })
export class Message extends BaseClass {

View File

@ -23,7 +23,6 @@ import {
PrimaryGeneratedColumn,
BaseEntity,
} from "typeorm";
import { dbEngine } from "../util/Database";
export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith(
"mongodb",
@ -33,7 +32,6 @@ export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith(
@Entity({
name: "migrations",
engine: dbEngine,
})
export class Migration extends BaseEntity {
@PrimaryIdAutoGenerated()

View File

@ -19,11 +19,9 @@
import { Column, Entity, JoinColumn, ManyToOne, Unique } from "typeorm";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import { dbEngine } from "../util/Database";
@Entity({
name: "notes",
engine: dbEngine,
})
@Unique(["owner", "target"])
export class Note extends BaseClass {

View File

@ -18,11 +18,9 @@
import { Column, Entity } from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "rate_limits",
engine: dbEngine,
})
export class RateLimit extends BaseClass {
@Column() // no relation as it also

View File

@ -27,7 +27,6 @@ import {
import { BaseClass } from "./BaseClass";
import { Channel } from "./Channel";
import { User } from "./User";
import { dbEngine } from "../util/Database";
// for read receipts
// notification cursor and public read receipt need to be forwards-only (the former to prevent re-pinging when marked as unread, and the latter to be acceptable as a legal acknowledgement in criminal proceedings), and private read marker needs to be advance-rewind capable
@ -35,7 +34,6 @@ import { dbEngine } from "../util/Database";
@Entity({
name: "read_states",
engine: dbEngine,
})
@Index(["channel_id", "user_id"], { unique: true })
export class ReadState extends BaseClass {

View File

@ -18,11 +18,9 @@
import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "recipients",
engine: dbEngine,
})
export class Recipient extends BaseClass {
@Column()

View File

@ -26,7 +26,6 @@ import {
} from "typeorm";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum RelationshipType {
outgoing = 4,
@ -37,7 +36,6 @@ export enum RelationshipType {
@Entity({
name: "relationships",
engine: dbEngine,
})
@Index(["from_id", "to_id"], { unique: true })
export class Relationship extends BaseClass {

View File

@ -20,7 +20,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { dbEngine } from "../util/Database";
export class RoleColors {
primary_color: number;
@ -38,7 +37,6 @@ export class RoleColors {
@Entity({
name: "roles",
engine: dbEngine,
})
export class Role extends BaseClass {
@Column()

View File

@ -19,11 +19,9 @@
import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import { dbEngine } from "../util/Database";
@Entity({
name: "security_keys",
engine: dbEngine,
})
export class SecurityKey extends BaseClass {
@Column({ nullable: true })

View File

@ -21,13 +21,11 @@ import { BaseClass } from "./BaseClass";
import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { ClientStatus, Status } from "../interfaces/Status";
import { Activity } from "../interfaces/Activity";
import { dbEngine } from "../util/Database";
//TODO we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them
@Entity({
name: "sessions",
engine: dbEngine,
})
export class Session extends BaseClass {
@Column({ nullable: true })

View File

@ -20,7 +20,6 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum StickerType {
STANDARD = 1,
@ -36,7 +35,6 @@ export enum StickerFormatType {
@Entity({
name: "stickers",
engine: dbEngine,
})
export class Sticker extends BaseClass {
@Column()

View File

@ -26,11 +26,9 @@ import {
} from "typeorm";
import { Sticker } from ".";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "sticker_packs",
engine: dbEngine,
})
export class StickerPack extends BaseClass {
@Column()

View File

@ -6,13 +6,11 @@ import {
RelationId,
} from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
import { User } from "./User";
import { Channel } from "./Channel";
@Entity({
name: "streams",
engine: dbEngine,
})
export class Stream extends BaseClass {
@Column()

View File

@ -6,13 +6,11 @@ import {
RelationId,
} from "typeorm";
import { BaseClass } from "./BaseClass";
import { dbEngine } from "../util/Database";
import { User } from "./User";
import { Stream } from "./Stream";
@Entity({
name: "stream_sessions",
engine: dbEngine,
})
export class StreamSession extends BaseClass {
@Column()

View File

@ -27,11 +27,9 @@ import {
import { BaseClass } from "./BaseClass";
import { TeamMember } from "./TeamMember";
import { User } from "./User";
import { dbEngine } from "../util/Database";
@Entity({
name: "teams",
engine: dbEngine,
})
export class Team extends BaseClass {
@Column({ nullable: true })

View File

@ -19,7 +19,6 @@
import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum TeamMemberState {
INVITED = 1,
@ -33,7 +32,6 @@ export enum TeamMemberRole {
@Entity({
name: "team_members",
engine: dbEngine,
})
export class TeamMember extends BaseClass {
@Column({ type: "int" })

View File

@ -20,11 +20,9 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { User } from "./User";
import { dbEngine } from "../util/Database";
@Entity({
name: "templates",
engine: dbEngine,
})
export class Template extends BaseClass {
@Column({ unique: true })

View File

@ -27,7 +27,6 @@ import { Relationship } from "./Relationship";
import { SecurityKey } from "./SecurityKey";
import { Session } from "./Session";
import { UserSettings } from "./UserSettings";
import { dbEngine } from "../util/Database";
export enum PublicUserEnum {
username,
@ -77,7 +76,6 @@ export interface UserPrivate extends Pick<User, PrivateUserKeys> {
@Entity({
name: "users",
engine: dbEngine,
})
export class User extends BaseClass {
@Column()

View File

@ -18,11 +18,9 @@
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { BaseClassWithoutId } from "./BaseClass";
import { dbEngine } from "../util/Database";
@Entity({
name: "user_settings",
engine: dbEngine,
})
export class UserSettings extends BaseClassWithoutId {
@PrimaryGeneratedColumn()

View File

@ -18,7 +18,6 @@
import { Column, Entity, JoinColumn, OneToOne } from "typeorm";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import { dbEngine } from "@spacebar/util";
import { User } from "./User";
import {
FrecencyUserSettings,
@ -32,7 +31,6 @@ import {
@Entity({
name: "user_settings_protos",
engine: dbEngine,
})
export class UserSettingsProtos extends BaseClassWithoutId {
@OneToOne(() => User, {

View File

@ -17,11 +17,9 @@
*/
import { BaseEntity, Column, Entity, PrimaryColumn } from "typeorm";
import { dbEngine } from "../util/Database";
@Entity({
name: "valid_registration_tokens",
engine: dbEngine,
})
export class ValidRegistrationToken extends BaseEntity {
@PrimaryColumn()

View File

@ -22,7 +22,6 @@ import { Channel } from "./Channel";
import { Guild } from "./Guild";
import { Member } from "./Member";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum PublicVoiceStateEnum {
user_id,
@ -50,7 +49,6 @@ export type PublicVoiceState = Pick<VoiceState, PublicVoiceStateKeys>;
//https://gist.github.com/vassjozsef/e482c65df6ee1facaace8b3c9ff66145#file-voice_state-ex
@Entity({
name: "voice_states",
engine: dbEngine,
})
export class VoiceState extends BaseClass {
@Column({ nullable: true })

View File

@ -22,7 +22,6 @@ import { BaseClass } from "./BaseClass";
import { Channel } from "./Channel";
import { Guild } from "./Guild";
import { User } from "./User";
import { dbEngine } from "../util/Database";
export enum WebhookType {
Incoming = 1,
@ -32,7 +31,6 @@ export enum WebhookType {
@Entity({
name: "webhooks",
engine: dbEngine,
})
export class Webhook extends BaseClass {
@Column({ type: "int" })

View File

@ -1,41 +0,0 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { MigrationInterface, QueryRunner } from "typeorm";
export class templateDeleteCascade1673609465036 implements MigrationInterface {
name = "templateDeleteCascade1673609465036";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_445d00eaaea0e60a017a5ed0c11\``,
);
await queryRunner.query(
`ALTER TABLE \`templates\` ADD CONSTRAINT \`FK_445d00eaaea0e60a017a5ed0c11\` FOREIGN KEY (\`source_guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_445d00eaaea0e60a017a5ed0c11\``,
);
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`,
);
}
}

View File

@ -1,45 +0,0 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { MigrationInterface, QueryRunner } from "typeorm";
export class webauthn1675045120206 implements MigrationInterface {
name = "webauthn1675045120206";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE \`security_keys\` (\`id\` varchar(255) NOT NULL, \`user_id\` varchar(255) NULL, \`key_id\` varchar(255) NOT NULL, \`public_key\` varchar(255) NOT NULL, \`counter\` int NOT NULL, \`name\` varchar(255) NOT NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
);
await queryRunner.query(
`ALTER TABLE \`users\` ADD \`webauthn_enabled\` tinyint NOT NULL DEFAULT 0`,
);
await queryRunner.query(
`ALTER TABLE \`security_keys\` ADD CONSTRAINT \`FK_24c97d0771cafedce6d7163eaad\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`security_keys\` DROP FOREIGN KEY \`FK_24c97d0771cafedce6d7163eaad\``,
);
await queryRunner.query(
`ALTER TABLE \`users\` DROP COLUMN \`webauthn_enabled\``,
);
await queryRunner.query(`DROP TABLE \`security_keys\``);
}
}

View File

@ -1,40 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class guildChannelOrdering1696420827239 implements MigrationInterface {
name = "guildChannelOrdering1696420827239";
public async up(queryRunner: QueryRunner): Promise<void> {
const guilds = await queryRunner.query(
`SELECT id FROM guilds`,
undefined,
true,
);
await queryRunner.query(
`ALTER TABLE guilds ADD channel_ordering text NOT NULL DEFAULT '[]'`,
);
for (const guild_id of guilds.records.map((x) => x.id)) {
const channels: Array<{ position: number; id: string }> = (
await queryRunner.query(
`SELECT id, position FROM channels WHERE guild_id = ?`,
[guild_id],
true,
)
).records;
channels.sort((a, b) => a.position - b.position);
await queryRunner.query(
`UPDATE guilds SET channel_ordering = ? WHERE id = ?`,
[JSON.stringify(channels.map((x) => x.id)), guild_id],
);
}
await queryRunner.query(`ALTER TABLE channels DROP COLUMN position`);
}
public async down(): Promise<void> {
// don't care actually, sorry.
}
}

View File

@ -1,25 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MessageFlagsNotNull1713116476900 implements MigrationInterface {
name = "MessageFlagsNotNull1713116476900";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` CHANGE flags flags_old integer;",
);
await queryRunner.query(
"ALTER TABLE `messages` ADD flags integer NOT NULL DEFAULT 0;",
);
await queryRunner.query(
"UPDATE `messages` SET flags = IFNULL(flags_old, 0);",
);
await queryRunner.query(
"ALTER TABLE `messages` DROP COLUMN flags_old;",
);
}
public async down(): Promise<void> {
// dont care
throw new Error("Migration down is not implemented.");
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class NewUserSettings1719776735000 implements MigrationInterface {
name = "NewUserSettings1719776735000";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
);
await queryRunner.query(
"ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
);
await queryRunner.query(
"ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
);
}
}

View File

@ -1,13 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MessagePollObject1720157926878 implements MigrationInterface {
name = "MessagePollObject1720157926878";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
}
}

View File

@ -1,21 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class Badges1720628601997 implements MigrationInterface {
name = "Badges1720628601997";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
);
await queryRunner.query(
`ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
);
await queryRunner.query(`DROP TABLE \`badges\``);
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class WebhookMessageProperties1721298824927
implements MigrationInterface
{
name = "WebhookMessageProperties1721298824927";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` ADD `username` text NULL",
);
await queryRunner.query(
"ALTER TABLE `messages` ADD `avatar` text NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` DROP COLUMN `username`",
);
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `avatar`");
}
}

View File

@ -1,17 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class client_status1723347738541 implements MigrationInterface {
name = "client_status1723347738541";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `sessions` ADD `client_status` text NULL AFTER `client_info`",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `sessions` DROP COLUMN `client_status`",
);
}
}

View File

@ -1,15 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class DiscoveryCategoryIcon1723577874393 implements MigrationInterface {
name = "DiscoveryCategoryIcon1723577874393";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `categories` ADD `icon` text NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `categories` DROP COLUMN `icon`");
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class WebhookSourceChannel1723644478176 implements MigrationInterface {
name = "WebhookSourceChannel1723644478176";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `webhooks` ADD COLUMN `source_channel_id` VARCHAR(255) NULL DEFAULT NULL AFTER `source_guild_id`",
);
await queryRunner.query(
"ALTER TABLE `webhooks` ADD CONSTRAINT `FK_d64f38834fa676f6caa4786ddd6` FOREIGN KEY (`source_channel_id`) REFERENCES `channels` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `webhooks` DROP FOREIGN KEY `FK_d64f38834fa676f6caa4786ddd6`",
);
await queryRunner.query(
"ALTER TABLE `webhooks` DROP COLUMN `source_channel_id`",
);
}
}

View File

@ -1,17 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class TeamMemberRole1724477620293 implements MigrationInterface {
name = "TeamMemberRole1724477620293";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `team_members` ADD COLUMN `role` VARCHAR(255) NOT NULL AFTER `permissions`",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `team_members` DROP COLUMN `role`",
);
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class ApplicationProperties1725090962922 implements MigrationInterface {
name = "ApplicationProperties1725090962922";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `applications` ADD COLUMN `guild_id` VARCHAR(255) DEFAULT NULL",
);
await queryRunner.query(
"ALTER TABLE `applications` ADD COLUMN `custom_install_url` TEXT DEFAULT NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `applications` DROP COLUMN `guild_id`",
);
await queryRunner.query(
"ALTER TABLE `applications` DROP COLUMN `custom_install_url`",
);
}
}

View File

@ -1,41 +0,0 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { MigrationInterface, QueryRunner } from "typeorm";
export class templateDeleteCascade1673609465036 implements MigrationInterface {
name = "templateDeleteCascade1673609465036";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_445d00eaaea0e60a017a5ed0c11\``,
);
await queryRunner.query(
`ALTER TABLE \`templates\` ADD CONSTRAINT \`FK_445d00eaaea0e60a017a5ed0c11\` FOREIGN KEY (\`source_guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`templates\` DROP FOREIGN KEY \`FK_445d00eaaea0e60a017a5ed0c11\``,
);
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`,
);
}
}

View File

@ -1,45 +0,0 @@
/*
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
Copyright (C) 2023 Spacebar and Spacebar Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { MigrationInterface, QueryRunner } from "typeorm";
export class webauthn1675045120206 implements MigrationInterface {
name = "webauthn1675045120206";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE \`security_keys\` (\`id\` varchar(255) NOT NULL, \`user_id\` varchar(255) NULL, \`key_id\` varchar(255) NOT NULL, \`public_key\` varchar(255) NOT NULL, \`counter\` int NOT NULL, \`name\` varchar(255) NOT NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
);
await queryRunner.query(
`ALTER TABLE \`users\` ADD \`webauthn_enabled\` tinyint NOT NULL DEFAULT 0`,
);
await queryRunner.query(
`ALTER TABLE \`security_keys\` ADD CONSTRAINT \`FK_24c97d0771cafedce6d7163eaad\` FOREIGN KEY (\`user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`security_keys\` DROP FOREIGN KEY \`FK_24c97d0771cafedce6d7163eaad\``,
);
await queryRunner.query(
`ALTER TABLE \`users\` DROP COLUMN \`webauthn_enabled\``,
);
await queryRunner.query(`DROP TABLE \`security_keys\``);
}
}

View File

@ -1,40 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class guildChannelOrdering1696420827239 implements MigrationInterface {
name = "guildChannelOrdering1696420827239";
public async up(queryRunner: QueryRunner): Promise<void> {
const guilds = await queryRunner.query(
`SELECT id FROM guilds`,
undefined,
true,
);
await queryRunner.query(
`ALTER TABLE guilds ADD channel_ordering text NOT NULL DEFAULT '[]'`,
);
for (const guild_id of guilds.records.map((x) => x.id)) {
const channels: Array<{ position: number; id: string }> = (
await queryRunner.query(
`SELECT id, position FROM channels WHERE guild_id = ?`,
[guild_id],
true,
)
).records;
channels.sort((a, b) => a.position - b.position);
await queryRunner.query(
`UPDATE guilds SET channel_ordering = ? WHERE id = ?`,
[JSON.stringify(channels.map((x) => x.id)), guild_id],
);
}
await queryRunner.query(`ALTER TABLE channels DROP COLUMN position`);
}
public async down(): Promise<void> {
// don't care actually, sorry.
}
}

View File

@ -1,25 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MessageFlagsNotNull1713116476900 implements MigrationInterface {
name = "MessageFlagsNotNull1713116476900";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` CHANGE flags flags_old integer;",
);
await queryRunner.query(
"ALTER TABLE `messages` ADD flags integer NOT NULL DEFAULT 0;",
);
await queryRunner.query(
"UPDATE `messages` SET flags = IFNULL(flags_old, 0);",
);
await queryRunner.query(
"ALTER TABLE `messages` DROP COLUMN flags_old;",
);
}
public async down(): Promise<void> {
// dont care
throw new Error("Migration down is not implemented.");
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class NewUserSettings1719776735000 implements MigrationInterface {
name = "NewUserSettings1719776735000";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
);
await queryRunner.query(
"ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
);
await queryRunner.query(
"ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
);
}
}

View File

@ -1,13 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MessagePollObject1720157926878 implements MigrationInterface {
name = "MessagePollObject1720157926878";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
}
}

View File

@ -1,21 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class Badges1720628601997 implements MigrationInterface {
name = "Badges1720628601997";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
);
await queryRunner.query(
`ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
);
await queryRunner.query(`DROP TABLE \`badges\``);
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class WebhookMessageProperties1721298824927
implements MigrationInterface
{
name = "WebhookMessageProperties1721298824927";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` ADD `username` text NULL",
);
await queryRunner.query(
"ALTER TABLE `messages` ADD `avatar` text NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `messages` DROP COLUMN `username`",
);
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `avatar`");
}
}

View File

@ -1,17 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class client_status1723347738541 implements MigrationInterface {
name = "client_status1723347738541";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `sessions` ADD `client_status` text NULL AFTER `client_info`",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `sessions` DROP COLUMN `client_status`",
);
}
}

View File

@ -1,15 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class DiscoveryCategoryIcon1723577874393 implements MigrationInterface {
name = "DiscoveryCategoryIcon1723577874393";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `categories` ADD `icon` text NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query("ALTER TABLE `categories` DROP COLUMN `icon`");
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class WebhookSourceChannel1723644478176 implements MigrationInterface {
name = "WebhookSourceChannel1723644478176";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `webhooks` ADD COLUMN `source_channel_id` VARCHAR(255) NULL DEFAULT NULL AFTER `source_guild_id`",
);
await queryRunner.query(
"ALTER TABLE `webhooks` ADD CONSTRAINT `FK_d64f38834fa676f6caa4786ddd6` FOREIGN KEY (`source_channel_id`) REFERENCES `channels` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `webhooks` DROP FOREIGN KEY `FK_d64f38834fa676f6caa4786ddd6`",
);
await queryRunner.query(
"ALTER TABLE `webhooks` DROP COLUMN `source_channel_id`",
);
}
}

View File

@ -1,17 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class TeamMemberRole1724477620293 implements MigrationInterface {
name = "TeamMemberRole1724477620293";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `team_members` ADD COLUMN `role` VARCHAR(255) NOT NULL AFTER `permissions`",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `team_members` DROP COLUMN `role`",
);
}
}

View File

@ -1,23 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class ApplicationProperties1725090962922 implements MigrationInterface {
name = "ApplicationProperties1725090962922";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `applications` ADD COLUMN `guild_id` VARCHAR(255) DEFAULT NULL",
);
await queryRunner.query(
"ALTER TABLE `applications` ADD COLUMN `custom_install_url` TEXT DEFAULT NULL",
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
"ALTER TABLE `applications` DROP COLUMN `guild_id`",
);
await queryRunner.query(
"ALTER TABLE `applications` DROP COLUMN `custom_install_url`",
);
}
}

View File

@ -26,7 +26,7 @@ import { Migration } from "../entities/Migration";
// 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 dbConnection: DataSource | undefined;
export let dbConnection: DataSource | undefined;
// For typeorm cli
if (!process.env) {
@ -36,14 +36,14 @@ if (!process.env) {
const dbConnectionString =
process.env.DATABASE || path.join(process.cwd(), "database.db");
const DatabaseType = dbConnectionString.includes("://")
export const DatabaseType = dbConnectionString.includes("://")
? dbConnectionString.split(":")[0]?.replace("+srv", "")
: "sqlite";
const isSqlite = DatabaseType.includes("sqlite");
const DataSourceOptions = new DataSource({
export const DataSourceOptions = new DataSource({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore type 'string' is not 'mysql' | 'sqlite' | 'mariadb' | etc etc
//@ts-ignore type 'string' is not 'sqlite' | 'postgres' | etc etc
type: DatabaseType,
charset: "utf8mb4",
url: isSqlite ? undefined : dbConnectionString,
@ -77,7 +77,7 @@ export async function initDatabase(): Promise<DataSource> {
}
if (!process.env.DB_SYNC) {
const supported = ["mysql", "mariadb", "postgres", "sqlite"];
const supported = ["postgres", "sqlite"];
if (!supported.includes(DatabaseType)) {
console.log(
"[Database]" +
@ -129,11 +129,6 @@ export async function initDatabase(): Promise<DataSource> {
return dbConnection;
}
export { DataSourceOptions, DatabaseType, dbConnection };
export async function closeDatabase() {
await dbConnection?.destroy();
}
export const dbEngine =
"InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";