Skip to content
This repository was archived by the owner on May 7, 2023. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3

- name: Install Node v16
- name: Install Node v18
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3
with:
node-version: 16
node-version: 18
cache: yarn

- name: Install Dependencies
Expand Down
24 changes: 14 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@
"start:dev": "NODE_ENV=development nodemon ./dist",
"start": "node ./dist",
"lint": "eslint src",
"postinstall": "is-ci || husky install"
"postinstall": "is-ci || husky install",
"prisma": "dotenv -e data/.env -- prisma"
},
"dependencies": {
"@prisma/client": "^4.7.1",
"@snowcrystals/iglo": "1.2.0",
"add": "^2.0.6",
"discord.js": "^14.7.1",
"dotenv": "^16.0.3",
"ms": "^2.1.3",
"yarn": "^1.22.19"
},
"devDependencies": {
"@commitlint/cli": "^17.3.0",
Expand All @@ -26,6 +36,7 @@
"@types/node": "^18.11.13",
"@typescript-eslint/eslint-plugin": "^5.46.0",
"@typescript-eslint/parser": "^5.46.0",
"dotenv-cli": "^6.0.0",
"eslint": "^8.29.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
Expand All @@ -34,18 +45,11 @@
"lint-staged": "^13.1.0",
"nodemon": "^2.0.20",
"prettier": "^2.8.1",
"prisma": "^4.7.1",
"typescript": "4.9.4"
},
"engines": {
"node": ">= v18.12.1"
},
"packageManager": "[email protected]",
"dependencies": {
"@snowcrystals/iglo": "1.2.0",
"add": "^2.0.6",
"discord.js": "^14.7.1",
"dotenv": "^16.0.3",
"ms": "^2.1.3",
"yarn": "^1.22.19"
}
"packageManager": "[email protected]"
}
87 changes: 87 additions & 0 deletions prisma/migrations/20221214162812_backup_model_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
-- CreateTable
CREATE TABLE "guild_backup" (
"backup_id" TEXT NOT NULL,
"backup_creation_date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"guild_name" TEXT NOT NULL,
"guild_id" TEXT,
"guild_icon" TEXT,
"inactive_channel_id" TEXT,
"inactive_channel_name" TEXT,
"inactive_timeout" INTEGER NOT NULL,
"system_channel_name" TEXT,
"system_channel_id" TEXT,
"system_enable_join" BOOLEAN NOT NULL,
"system_enable_sticker" BOOLEAN NOT NULL,
"system_enable_boost" BOOLEAN NOT NULL,
"system_enable_tips" BOOLEAN NOT NULL,
"nitro_progress_enabled" BOOLEAN NOT NULL,
"invite_banner" TEXT,
"guild_banner" TEXT,
"widget_enabled" BOOLEAN NOT NULL,
"widget_channel_name" TEXT,
"widget_channel_id" TEXT,

CONSTRAINT "guild_backup_pkey" PRIMARY KEY ("backup_id")
);

-- CreateTable
CREATE TABLE "BackUpRole" (
"backup_id" TEXT NOT NULL,
"role_id" TEXT,
"role_name" TEXT NOT NULL,
"role_position" INTEGER NOT NULL,
"role_icon" TEXT NOT NULL,
"role_color" TEXT NOT NULL,
"role_mention_everyone" BOOLEAN NOT NULL,
"role_display_separate" BOOLEAN NOT NULL,
"role_permissions" BIGINT NOT NULL,
"role_members" TEXT[],
"backUpBackUpId" TEXT,

CONSTRAINT "BackUpRole_pkey" PRIMARY KEY ("backup_id")
);

-- CreateTable
CREATE TABLE "BackUpBan" (
"backup_id" TEXT NOT NULL,
"ban_user_id" TEXT NOT NULL,
"ban_reason" TEXT NOT NULL,
"backUpBackUpId" TEXT,

CONSTRAINT "BackUpBan_pkey" PRIMARY KEY ("backup_id")
);

-- CreateTable
CREATE TABLE "BackUpEmoji" (
"backup_id" TEXT NOT NULL,
"emoji_id" TEXT NOT NULL,
"emoji_hash" TEXT NOT NULL,
"backUpBackUpId" TEXT,

CONSTRAINT "BackUpEmoji_pkey" PRIMARY KEY ("backup_id")
);

-- CreateTable
CREATE TABLE "BackUpSticker" (
"backup_id" TEXT NOT NULL,
"sticker_id" TEXT,
"sticker_name" TEXT NOT NULL,
"sticker_related_emoji" TEXT NOT NULL,
"sticker_description" TEXT NOT NULL,
"sticker_hash" TEXT NOT NULL,
"backUpBackUpId" TEXT,

CONSTRAINT "BackUpSticker_pkey" PRIMARY KEY ("backup_id")
);

-- AddForeignKey
ALTER TABLE "BackUpRole" ADD CONSTRAINT "BackUpRole_backUpBackUpId_fkey" FOREIGN KEY ("backUpBackUpId") REFERENCES "guild_backup"("backup_id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "BackUpBan" ADD CONSTRAINT "BackUpBan_backUpBackUpId_fkey" FOREIGN KEY ("backUpBackUpId") REFERENCES "guild_backup"("backup_id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "BackUpEmoji" ADD CONSTRAINT "BackUpEmoji_backUpBackUpId_fkey" FOREIGN KEY ("backUpBackUpId") REFERENCES "guild_backup"("backup_id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "BackUpSticker" ADD CONSTRAINT "BackUpSticker_backUpBackUpId_fkey" FOREIGN KEY ("backUpBackUpId") REFERENCES "guild_backup"("backup_id") ON DELETE SET NULL ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:

- Added the required column `backup_secret` to the `guild_backup` table without a default value. This is not possible if the table is not empty.

*/
-- AlterTable
ALTER TABLE "guild_backup" ADD COLUMN "backup_secret" TEXT NOT NULL;
3 changes: 3 additions & 0 deletions prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
104 changes: 104 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}

model BackUp {
backUpId String @id @map("backup_id")
secret String @map("backup_secret")

createdAt DateTime @default(now()) @map("backup_creation_date")

guildName String @map("guild_name")
guildId String? @map("guild_id")
guildIcon String? @map("guild_icon") // guildIconHash

inactiveChannelId String? @map("inactive_channel_id")
inactiveChannelName String? @map("inactive_channel_name") // fallback for when data is imported from one server to another or when channel is deleted
inactiveTimeout Int @map("inactive_timeout")

systemChannelName String? @map("system_channel_name")
systemChannelId String? @map("system_channel_id")
systemEnableJoin Boolean @map("system_enable_join")
systemEnableSticker Boolean @map("system_enable_sticker")
systemEnableBoost Boolean @map("system_enable_boost")
systemEnableTips Boolean @map("system_enable_tips")

nitroProgressEnabled Boolean @map("nitro_progress_enabled")
inviteBackground String? @map("invite_banner") // imageHash
guildBanner String? @map("guild_banner") // imageHash

widgetEnabled Boolean @map("widget_enabled")
widgetChannelName String? @map("widget_channel_name")
widgetChannelId String? @map("widget_channel_id") // Both can be undefined if no invite is chosen

roles BackUpRole[]
bans BackUpBan[]
emojis BackUpEmoji[]
stickers BackUpSticker[]
// TODO: Add Automod & Community data fields

@@map("guild_backup")
}

model BackUpRole {
backUpId String @id @map("backup_id")

id String? @map("role_id")
name String @map("role_name")
position Int @map("role_position")

icon String @map("role_icon") // imageHash
color String @map("role_color")

mentionEveryone Boolean @map("role_mention_everyone")
displaySeparate Boolean @map("role_display_separate")

permissions BigInt @map("role_permissions")
members String[] @map("role_members") // list of members with the role (ID)

BackUp BackUp? @relation(fields: [backUpBackUpId], references: [backUpId])
backUpBackUpId String?
}

model BackUpBan {
backUpId String @id @map("backup_id")

userId String @map("ban_user_id")
reason String @map("ban_reason")

BackUp BackUp? @relation(fields: [backUpBackUpId], references: [backUpId])
backUpBackUpId String?
}

model BackUpEmoji {
backUpId String @id @map("backup_id")

name String @map("emoji_id")
emoji String @map("emoji_hash")

BackUp BackUp? @relation(fields: [backUpBackUpId], references: [backUpId])
backUpBackUpId String?
}

model BackUpSticker {
backUpId String @id @map("backup_id")

id String? @map("sticker_id")
name String @map("sticker_name")

emoji String @map("sticker_related_emoji")
description String @map("sticker_description")
sticker String @map("sticker_hash")

BackUp BackUp? @relation(fields: [backUpBackUpId], references: [backUpId])
backUpBackUpId String?
}
10 changes: 10 additions & 0 deletions src/lib/structures/BackItUpGuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type BackItUpClient from "../Client.js";
import type { BackItUpSettings } from "./type.js";

export class BackItUpGuild {
public backUpIds: string[];

public constructor(public client: BackItUpClient, data: BackItUpSettings) {
this.backUpIds = data.backUpIds;
}
}
80 changes: 80 additions & 0 deletions src/lib/structures/BackUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { Guild } from "discord.js";
import type BackItUpClient from "../Client.js";
import type { BackUpBan, BackUpData, BackUpEmoji, RawBackUp, BackUpSticker, BackUpRole } from "./type.js";

export default class BackUp {
public guild!: Guild;
public id: string;

public constructor(public client: BackItUpClient, public data: BackUpData) {
this.id = data.guild.id;
}

public loadGuild(): boolean {
const guild = this.data.guild.id
? this.client.guilds.cache.get(this.data.guild.id)
: this.client.guilds.cache.find((g) => g.name === this.data.guild.name);
if (!guild) return false;

this.guild = guild;
return true;
}

public static parse(client: BackItUpClient, data: RawBackUp) {
const bans = data.bans.map<BackUpBan>((ban) => ({ member: ban.userId, reason: ban.reason }));
const emojis = data.emojis.map<BackUpEmoji>((emoji) => ({ name: emoji.name, image: emoji.emoji }));
const stickers = data.stickers.map<BackUpSticker>((sticker) => ({
name: sticker.name,
emoji: sticker.emoji,
description: sticker.description,
image: sticker.sticker
}));
const roles = data.roles.map<BackUpRole>((role) => ({
name: role.name,
id: role.id ?? undefined,
postion: role.position,
permissions: role.permissions,
color: role.color,
display: role.displaySeparate,
members: role.members,
mention: role.mentionEveryone,
icon: role.icon ?? undefined
}));

const backUp: BackUpData = {
guild: {
id: data.backUpId,
name: data.guildName,
nitroProgress: data.nitroProgressEnabled,
banner: data.guildBanner ?? undefined,
icon: data.guildIcon ?? undefined,
guildId: data.guildId ?? undefined,
inviteBackground: data.inviteBackground ?? undefined,
inactive: {
channelId: data.inactiveChannelId ?? undefined,
channelName: data.inactiveChannelName ?? undefined,
timeout: data.inactiveTimeout
},
system: {
channelId: data.systemChannelId ?? undefined,
channelName: data.systemChannelName ?? undefined,
join: data.systemEnableJoin,
boost: data.systemEnableBoost,
tips: data.systemEnableTips,
stickerButton: data.systemEnableSticker
}
},
widget: {
enabled: data.widgetEnabled,
channelId: data.widgetChannelId ?? undefined,
channelName: data.widgetChannelName ?? undefined
},
bans,
emojis,
roles,
stickers
};

return new BackUp(client, backUp);
}
}
Loading