summary refs log tree commit diff
path: root/src/api/routes/guilds/#guild_id
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/routes/guilds/#guild_id')
-rw-r--r--src/api/routes/guilds/#guild_id/audit-logs.ts2
-rw-r--r--src/api/routes/guilds/#guild_id/bans.ts304
-rw-r--r--src/api/routes/guilds/#guild_id/channels.ts101
-rw-r--r--src/api/routes/guilds/#guild_id/delete.ts26
-rw-r--r--src/api/routes/guilds/#guild_id/discovery-requirements.ts46
-rw-r--r--src/api/routes/guilds/#guild_id/emojis.ts157
-rw-r--r--src/api/routes/guilds/#guild_id/index.ts106
-rw-r--r--src/api/routes/guilds/#guild_id/invites.ts17
-rw-r--r--src/api/routes/guilds/#guild_id/member-verification.ts4
-rw-r--r--src/api/routes/guilds/#guild_id/members/#member_id/index.ts110
-rw-r--r--src/api/routes/guilds/#guild_id/members/#member_id/nick.ts28
-rw-r--r--src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts28
-rw-r--r--src/api/routes/guilds/#guild_id/members/index.ts5
-rw-r--r--src/api/routes/guilds/#guild_id/messages/search.ts100
-rw-r--r--src/api/routes/guilds/#guild_id/prune.ts75
-rw-r--r--src/api/routes/guilds/#guild_id/regions.ts7
-rw-r--r--src/api/routes/guilds/#guild_id/roles/#role_id/index.ts107
-rw-r--r--src/api/routes/guilds/#guild_id/roles/index.ts139
-rw-r--r--src/api/routes/guilds/#guild_id/stickers.ts56
-rw-r--r--src/api/routes/guilds/#guild_id/templates.ts132
-rw-r--r--src/api/routes/guilds/#guild_id/vanity-url.ts120
-rw-r--r--src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts93
-rw-r--r--src/api/routes/guilds/#guild_id/welcome-screen.ts40
-rw-r--r--src/api/routes/guilds/#guild_id/widget.json.ts29
-rw-r--r--src/api/routes/guilds/#guild_id/widget.png.ts92
-rw-r--r--src/api/routes/guilds/#guild_id/widget.ts33
26 files changed, 1235 insertions, 722 deletions
diff --git a/src/api/routes/guilds/#guild_id/audit-logs.ts b/src/api/routes/guilds/#guild_id/audit-logs.ts
index b54835fc..76a11f6b 100644
--- a/src/api/routes/guilds/#guild_id/audit-logs.ts
+++ b/src/api/routes/guilds/#guild_id/audit-logs.ts
@@ -11,7 +11,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 		webhooks: [],
 		guild_scheduled_events: [],
 		threads: [],
-		application_commands: []
+		application_commands: [],
 	});
 });
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts
index ed00f9c0..930985d7 100644
--- a/src/api/routes/guilds/#guild_id/bans.ts
+++ b/src/api/routes/guilds/#guild_id/bans.ts
@@ -1,5 +1,15 @@
 import { Request, Response, Router } from "express";
-import { DiscordApiErrors, emitEvent, GuildBanAddEvent, GuildBanRemoveEvent, Ban, User, Member, BanRegistrySchema, BanModeratorSchema } from "@fosscord/util";
+import {
+	DiscordApiErrors,
+	emitEvent,
+	GuildBanAddEvent,
+	GuildBanRemoveEvent,
+	Ban,
+	User,
+	Member,
+	BanRegistrySchema,
+	BanModeratorSchema,
+} from "@fosscord/util";
 import { HTTPError } from "lambert-server";
 import { getIpAdress, route } from "@fosscord/api";
 
@@ -7,150 +17,184 @@ const router: Router = Router();
 
 /* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */
 
-router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
+router.get(
+	"/",
+	route({ permission: "BAN_MEMBERS" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
 
-	let bans = await Ban.find({ where: { guild_id: guild_id } });
-	let promisesToAwait: object[] = [];
-	const bansObj: object[] = [];
+		let bans = await Ban.find({ where: { guild_id: guild_id } });
+		let promisesToAwait: object[] = [];
+		const bansObj: object[] = [];
 
-	bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
+		bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
 
-	bans.forEach((ban) => {
-		promisesToAwait.push(User.getPublicUser(ban.user_id));
-	});
-
-	const bannedUsers: object[] = await Promise.all(promisesToAwait);
-
-	bans.forEach((ban, index) => {
-		const user = bannedUsers[index] as User;
-		bansObj.push({
-			reason: ban.reason,
-			user: {
-				username: user.username,
-				discriminator: user.discriminator,
-				id: user.id,
-				avatar: user.avatar,
-				public_flags: user.public_flags
-			}
+		bans.forEach((ban) => {
+			promisesToAwait.push(User.getPublicUser(ban.user_id));
 		});
-	});
-
-	return res.json(bansObj);
-});
-
-router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const user_id = req.params.ban;
-
-	let ban = await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id } }) as BanRegistrySchema;
-
-	if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN;
-	// pretend self-bans don't exist to prevent victim chasing
-
-	/* Filter secret from registry. */
-
-	ban = ban as BanModeratorSchema;
-
-	delete ban.ip;
-
-	return res.json(ban);
-});
-
-router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const banned_user_id = req.params.user_id;
 
-	if ((req.user_id === banned_user_id) && (banned_user_id === req.permission!.cache.guild?.owner_id))
-		throw new HTTPError("You are the guild owner, hence can't ban yourself", 403);
-
-	if (req.permission!.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400);
-
-	const banned_user = await User.getPublicUser(banned_user_id);
+		const bannedUsers: object[] = await Promise.all(promisesToAwait);
+
+		bans.forEach((ban, index) => {
+			const user = bannedUsers[index] as User;
+			bansObj.push({
+				reason: ban.reason,
+				user: {
+					username: user.username,
+					discriminator: user.discriminator,
+					id: user.id,
+					avatar: user.avatar,
+					public_flags: user.public_flags,
+				},
+			});
+		});
 
-	const ban = Ban.create({
-		user_id: banned_user_id,
-		guild_id: guild_id,
-		ip: getIpAdress(req),
-		executor_id: req.user_id,
-		reason: req.body.reason // || otherwise empty
-	});
+		return res.json(bansObj);
+	},
+);
+
+router.get(
+	"/:user",
+	route({ permission: "BAN_MEMBERS" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const user_id = req.params.ban;
+
+		let ban = (await Ban.findOneOrFail({
+			where: { guild_id: guild_id, user_id: user_id },
+		})) as BanRegistrySchema;
+
+		if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN;
+		// pretend self-bans don't exist to prevent victim chasing
+
+		/* Filter secret from registry. */
+
+		ban = ban as BanModeratorSchema;
+
+		delete ban.ip;
+
+		return res.json(ban);
+	},
+);
+
+router.put(
+	"/:user_id",
+	route({ body: "BanCreateSchema", permission: "BAN_MEMBERS" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const banned_user_id = req.params.user_id;
+
+		if (
+			req.user_id === banned_user_id &&
+			banned_user_id === req.permission!.cache.guild?.owner_id
+		)
+			throw new HTTPError(
+				"You are the guild owner, hence can't ban yourself",
+				403,
+			);
+
+		if (req.permission!.cache.guild?.owner_id === banned_user_id)
+			throw new HTTPError("You can't ban the owner", 400);
+
+		const banned_user = await User.getPublicUser(banned_user_id);
+
+		const ban = Ban.create({
+			user_id: banned_user_id,
+			guild_id: guild_id,
+			ip: getIpAdress(req),
+			executor_id: req.user_id,
+			reason: req.body.reason, // || otherwise empty
+		});
 
-	await Promise.all([
-		Member.removeFromGuild(banned_user_id, guild_id),
-		ban.save(),
-		emitEvent({
-			event: "GUILD_BAN_ADD",
-			data: {
-				guild_id: guild_id,
-				user: banned_user
-			},
-			guild_id: guild_id
-		} as GuildBanAddEvent)
-	]);
-
-	return res.json(ban);
-});
-
-router.put("/@me", route({ body: "BanCreateSchema" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-
-	const banned_user = await User.getPublicUser(req.params.user_id);
-
-	if (req.permission!.cache.guild?.owner_id === req.params.user_id)
-		throw new HTTPError("You are the guild owner, hence can't ban yourself", 403);
-
-	const ban = Ban.create({
-		user_id: req.params.user_id,
-		guild_id: guild_id,
-		ip: getIpAdress(req),
-		executor_id: req.params.user_id,
-		reason: req.body.reason // || otherwise empty
-	});
-
-	await Promise.all([
-		Member.removeFromGuild(req.user_id, guild_id),
-		ban.save(),
-		emitEvent({
-			event: "GUILD_BAN_ADD",
-			data: {
+		await Promise.all([
+			Member.removeFromGuild(banned_user_id, guild_id),
+			ban.save(),
+			emitEvent({
+				event: "GUILD_BAN_ADD",
+				data: {
+					guild_id: guild_id,
+					user: banned_user,
+				},
 				guild_id: guild_id,
-				user: banned_user
-			},
-			guild_id: guild_id
-		} as GuildBanAddEvent)
-	]);
+			} as GuildBanAddEvent),
+		]);
+
+		return res.json(ban);
+	},
+);
+
+router.put(
+	"/@me",
+	route({ body: "BanCreateSchema" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+
+		const banned_user = await User.getPublicUser(req.params.user_id);
+
+		if (req.permission!.cache.guild?.owner_id === req.params.user_id)
+			throw new HTTPError(
+				"You are the guild owner, hence can't ban yourself",
+				403,
+			);
+
+		const ban = Ban.create({
+			user_id: req.params.user_id,
+			guild_id: guild_id,
+			ip: getIpAdress(req),
+			executor_id: req.params.user_id,
+			reason: req.body.reason, // || otherwise empty
+		});
 
-	return res.json(ban);
-});
+		await Promise.all([
+			Member.removeFromGuild(req.user_id, guild_id),
+			ban.save(),
+			emitEvent({
+				event: "GUILD_BAN_ADD",
+				data: {
+					guild_id: guild_id,
+					user: banned_user,
+				},
+				guild_id: guild_id,
+			} as GuildBanAddEvent),
+		]);
 
-router.delete("/:user_id", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
-	const { guild_id, user_id } = req.params;
+		return res.json(ban);
+	},
+);
 
-	let ban = await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id } });
+router.delete(
+	"/:user_id",
+	route({ permission: "BAN_MEMBERS" }),
+	async (req: Request, res: Response) => {
+		const { guild_id, user_id } = req.params;
 
-	if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN;
-	// make self-bans irreversible and hide them from view to avoid victim chasing
+		let ban = await Ban.findOneOrFail({
+			where: { guild_id: guild_id, user_id: user_id },
+		});
 
-	const banned_user = await User.getPublicUser(user_id);
+		if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN;
+		// make self-bans irreversible and hide them from view to avoid victim chasing
 
-	await Promise.all([
-		Ban.delete({
-			user_id: user_id,
-			guild_id
-		}),
+		const banned_user = await User.getPublicUser(user_id);
 
-		emitEvent({
-			event: "GUILD_BAN_REMOVE",
-			data: {
+		await Promise.all([
+			Ban.delete({
+				user_id: user_id,
 				guild_id,
-				user: banned_user
-			},
-			guild_id
-		} as GuildBanRemoveEvent)
-	]);
-
-	return res.status(204).send();
-});
+			}),
+
+			emitEvent({
+				event: "GUILD_BAN_REMOVE",
+				data: {
+					guild_id,
+					user: banned_user,
+				},
+				guild_id,
+			} as GuildBanRemoveEvent),
+		]);
+
+		return res.status(204).send();
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts
index 7a5b50d1..af17465d 100644
--- a/src/api/routes/guilds/#guild_id/channels.ts
+++ b/src/api/routes/guilds/#guild_id/channels.ts
@@ -1,5 +1,10 @@
 import { Router, Response, Request } from "express";
-import { Channel, ChannelUpdateEvent, emitEvent, ChannelModifySchema } from "@fosscord/util";
+import {
+	Channel,
+	ChannelUpdateEvent,
+	emitEvent,
+	ChannelModifySchema,
+} from "@fosscord/util";
 import { HTTPError } from "lambert-server";
 import { route } from "@fosscord/api";
 const router = Router();
@@ -11,49 +16,77 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json(channels);
 });
 
-router.post("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => {
-	// creates a new guild channel https://discord.com/developers/docs/resources/guild#create-guild-channel
-	const { guild_id } = req.params;
-	const body = req.body as ChannelModifySchema;
+router.post(
+	"/",
+	route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }),
+	async (req: Request, res: Response) => {
+		// creates a new guild channel https://discord.com/developers/docs/resources/guild#create-guild-channel
+		const { guild_id } = req.params;
+		const body = req.body as ChannelModifySchema;
 
-	const channel = await Channel.createChannel({ ...body, guild_id }, req.user_id);
+		const channel = await Channel.createChannel(
+			{ ...body, guild_id },
+			req.user_id,
+		);
 
-	res.status(201).json(channel);
-});
+		res.status(201).json(channel);
+	},
+);
 
-export type ChannelReorderSchema = { id: string; position?: number; lock_permissions?: boolean; parent_id?: string; }[];
+export type ChannelReorderSchema = {
+	id: string;
+	position?: number;
+	lock_permissions?: boolean;
+	parent_id?: string;
+}[];
 
-router.patch("/", route({ body: "ChannelReorderSchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => {
-	// changes guild channel position
-	const { guild_id } = req.params;
-	const body = req.body as ChannelReorderSchema;
+router.patch(
+	"/",
+	route({ body: "ChannelReorderSchema", permission: "MANAGE_CHANNELS" }),
+	async (req: Request, res: Response) => {
+		// changes guild channel position
+		const { guild_id } = req.params;
+		const body = req.body as ChannelReorderSchema;
 
-	await Promise.all([
-		body.map(async (x) => {
-			if (x.position == null && !x.parent_id) throw new HTTPError(`You need to at least specify position or parent_id`, 400);
+		await Promise.all([
+			body.map(async (x) => {
+				if (x.position == null && !x.parent_id)
+					throw new HTTPError(
+						`You need to at least specify position or parent_id`,
+						400,
+					);
 
-			const opts: any = {};
-			if (x.position != null) opts.position = x.position;
+				const opts: any = {};
+				if (x.position != null) opts.position = x.position;
 
-			if (x.parent_id) {
-				opts.parent_id = x.parent_id;
-				const parent_channel = await Channel.findOneOrFail({
-					where: { id: x.parent_id, guild_id },
-					select: ["permission_overwrites"]
-				});
-				if (x.lock_permissions) {
-					opts.permission_overwrites = parent_channel.permission_overwrites;
+				if (x.parent_id) {
+					opts.parent_id = x.parent_id;
+					const parent_channel = await Channel.findOneOrFail({
+						where: { id: x.parent_id, guild_id },
+						select: ["permission_overwrites"],
+					});
+					if (x.lock_permissions) {
+						opts.permission_overwrites =
+							parent_channel.permission_overwrites;
+					}
 				}
-			}
 
-			await Channel.update({ guild_id, id: x.id }, opts);
-			const channel = await Channel.findOneOrFail({ where: { guild_id, id: x.id } });
+				await Channel.update({ guild_id, id: x.id }, opts);
+				const channel = await Channel.findOneOrFail({
+					where: { guild_id, id: x.id },
+				});
 
-			await emitEvent({ event: "CHANNEL_UPDATE", data: channel, channel_id: x.id, guild_id } as ChannelUpdateEvent);
-		})
-	]);
+				await emitEvent({
+					event: "CHANNEL_UPDATE",
+					data: channel,
+					channel_id: x.id,
+					guild_id,
+				} as ChannelUpdateEvent);
+			}),
+		]);
 
-	res.sendStatus(204);
-});
+		res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/delete.ts b/src/api/routes/guilds/#guild_id/delete.ts
index bd158c56..b951e4f4 100644
--- a/src/api/routes/guilds/#guild_id/delete.ts
+++ b/src/api/routes/guilds/#guild_id/delete.ts
@@ -1,4 +1,14 @@
-import { Channel, emitEvent, GuildDeleteEvent, Guild, Member, Message, Role, Invite, Emoji } from "@fosscord/util";
+import {
+	Channel,
+	emitEvent,
+	GuildDeleteEvent,
+	Guild,
+	Member,
+	Message,
+	Role,
+	Invite,
+	Emoji,
+} from "@fosscord/util";
 import { Router, Request, Response } from "express";
 import { HTTPError } from "lambert-server";
 import { route } from "@fosscord/api";
@@ -10,18 +20,22 @@ const router = Router();
 router.post("/", route({}), async (req: Request, res: Response) => {
 	var { guild_id } = req.params;
 
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: ["owner_id"] });
-	if (guild.owner_id !== req.user_id) throw new HTTPError("You are not the owner of this guild", 401);
+	const guild = await Guild.findOneOrFail({
+		where: { id: guild_id },
+		select: ["owner_id"],
+	});
+	if (guild.owner_id !== req.user_id)
+		throw new HTTPError("You are not the owner of this guild", 401);
 
 	await Promise.all([
 		Guild.delete({ id: guild_id }), // this will also delete all guild related data
 		emitEvent({
 			event: "GUILD_DELETE",
 			data: {
-				id: guild_id
+				id: guild_id,
 			},
-			guild_id: guild_id
-		} as GuildDeleteEvent)
+			guild_id: guild_id,
+		} as GuildDeleteEvent),
 	]);
 
 	return res.sendStatus(204);
diff --git a/src/api/routes/guilds/#guild_id/discovery-requirements.ts b/src/api/routes/guilds/#guild_id/discovery-requirements.ts
index ad20633f..7e63c06b 100644
--- a/src/api/routes/guilds/#guild_id/discovery-requirements.ts
+++ b/src/api/routes/guilds/#guild_id/discovery-requirements.ts
@@ -6,33 +6,33 @@ import { route } from "@fosscord/api";
 const router = Router();
 
 router.get("/", route({}), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;	
-    // TODO:
-    // Load from database
-    // Admin control, but for now it allows anyone to be discoverable
+	const { guild_id } = req.params;
+	// TODO:
+	// Load from database
+	// Admin control, but for now it allows anyone to be discoverable
 
 	res.send({
 		guild_id: guild_id,
 		safe_environment: true,
-        healthy: true,
-        health_score_pending: false,
-        size: true,
-        nsfw_properties: {},
-        protected: true,
-        sufficient: true,
-        sufficient_without_grace_period: true,
-        valid_rules_channel: true,
-        retention_healthy: true,
-        engagement_healthy: true,
-        age: true,
-        minimum_age: 0,
-        health_score: {
-            avg_nonnew_participators: 0,
-            avg_nonnew_communicators: 0,
-            num_intentful_joiners: 0,
-            perc_ret_w1_intentful: 0
-        },
-        minimum_size: 0
+		healthy: true,
+		health_score_pending: false,
+		size: true,
+		nsfw_properties: {},
+		protected: true,
+		sufficient: true,
+		sufficient_without_grace_period: true,
+		valid_rules_channel: true,
+		retention_healthy: true,
+		engagement_healthy: true,
+		age: true,
+		minimum_age: 0,
+		health_score: {
+			avg_nonnew_participators: 0,
+			avg_nonnew_communicators: 0,
+			num_intentful_joiners: 0,
+			perc_ret_w1_intentful: 0,
+		},
+		minimum_size: 0,
 	});
 });
 
diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts
index cf9d742a..6e8570eb 100644
--- a/src/api/routes/guilds/#guild_id/emojis.ts
+++ b/src/api/routes/guilds/#guild_id/emojis.ts
@@ -1,5 +1,17 @@
 import { Router, Request, Response } from "express";
-import { Config, DiscordApiErrors, emitEvent, Emoji, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User, EmojiCreateSchema, EmojiModifySchema } from "@fosscord/util";
+import {
+	Config,
+	DiscordApiErrors,
+	emitEvent,
+	Emoji,
+	GuildEmojisUpdateEvent,
+	handleFile,
+	Member,
+	Snowflake,
+	User,
+	EmojiCreateSchema,
+	EmojiModifySchema,
+} from "@fosscord/util";
 import { route } from "@fosscord/api";
 
 const router = Router();
@@ -9,7 +21,10 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 
 	await Member.IsInGuildOrFail(req.user_id, guild_id);
 
-	const emojis = await Emoji.find({ where: { guild_id: guild_id }, relations: ["user"] });
+	const emojis = await Emoji.find({
+		where: { guild_id: guild_id },
+		relations: ["user"],
+	});
 
 	return res.json(emojis);
 });
@@ -19,89 +34,115 @@ router.get("/:emoji_id", route({}), async (req: Request, res: Response) => {
 
 	await Member.IsInGuildOrFail(req.user_id, guild_id);
 
-	const emoji = await Emoji.findOneOrFail({ where: { guild_id: guild_id, id: emoji_id }, relations: ["user"] });
+	const emoji = await Emoji.findOneOrFail({
+		where: { guild_id: guild_id, id: emoji_id },
+		relations: ["user"],
+	});
 
 	return res.json(emoji);
 });
 
-router.post("/", route({ body: "EmojiCreateSchema", permission: "MANAGE_EMOJIS_AND_STICKERS" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const body = req.body as EmojiCreateSchema;
-
-	const id = Snowflake.generate();
-	const emoji_count = await Emoji.count({ where: { guild_id: guild_id } });
-	const { maxEmojis } = Config.get().limits.guild;
-
-	if (emoji_count >= maxEmojis) throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams(maxEmojis);
-	if (body.require_colons == null) body.require_colons = true;
-
-	const user = await User.findOneOrFail({ where: { id: req.user_id } });
-	body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
-
-	const emoji = await Emoji.create({
-		id: id,
-		guild_id: guild_id,
-		...body,
-		require_colons: body.require_colons ?? undefined,	// schema allows nulls, db does not
-		user: user,
-		managed: false,
-		animated: false, // TODO: Add support animated emojis
-		available: true,
-		roles: []
-	}).save();
-
-	await emitEvent({
-		event: "GUILD_EMOJIS_UPDATE",
-		guild_id: guild_id,
-		data: {
+router.post(
+	"/",
+	route({
+		body: "EmojiCreateSchema",
+		permission: "MANAGE_EMOJIS_AND_STICKERS",
+	}),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const body = req.body as EmojiCreateSchema;
+
+		const id = Snowflake.generate();
+		const emoji_count = await Emoji.count({
+			where: { guild_id: guild_id },
+		});
+		const { maxEmojis } = Config.get().limits.guild;
+
+		if (emoji_count >= maxEmojis)
+			throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams(
+				maxEmojis,
+			);
+		if (body.require_colons == null) body.require_colons = true;
+
+		const user = await User.findOneOrFail({ where: { id: req.user_id } });
+		body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
+
+		const emoji = await Emoji.create({
+			id: id,
 			guild_id: guild_id,
-			emojis: await Emoji.find({ where: { guild_id: guild_id } })
-		}
-	} as GuildEmojisUpdateEvent);
+			...body,
+			require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not
+			user: user,
+			managed: false,
+			animated: false, // TODO: Add support animated emojis
+			available: true,
+			roles: [],
+		}).save();
 
-	return res.status(201).json(emoji);
-});
+		await emitEvent({
+			event: "GUILD_EMOJIS_UPDATE",
+			guild_id: guild_id,
+			data: {
+				guild_id: guild_id,
+				emojis: await Emoji.find({ where: { guild_id: guild_id } }),
+			},
+		} as GuildEmojisUpdateEvent);
+
+		return res.status(201).json(emoji);
+	},
+);
 
 router.patch(
 	"/:emoji_id",
-	route({ body: "EmojiModifySchema", permission: "MANAGE_EMOJIS_AND_STICKERS" }),
+	route({
+		body: "EmojiModifySchema",
+		permission: "MANAGE_EMOJIS_AND_STICKERS",
+	}),
 	async (req: Request, res: Response) => {
 		const { emoji_id, guild_id } = req.params;
 		const body = req.body as EmojiModifySchema;
 
-		const emoji = await Emoji.create({ ...body, id: emoji_id, guild_id: guild_id }).save();
+		const emoji = await Emoji.create({
+			...body,
+			id: emoji_id,
+			guild_id: guild_id,
+		}).save();
 
 		await emitEvent({
 			event: "GUILD_EMOJIS_UPDATE",
 			guild_id: guild_id,
 			data: {
 				guild_id: guild_id,
-				emojis: await Emoji.find({ where: { guild_id: guild_id } })
-			}
+				emojis: await Emoji.find({ where: { guild_id: guild_id } }),
+			},
 		} as GuildEmojisUpdateEvent);
 
 		return res.json(emoji);
-	}
+	},
 );
 
-router.delete("/:emoji_id", route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }), async (req: Request, res: Response) => {
-	const { emoji_id, guild_id } = req.params;
+router.delete(
+	"/:emoji_id",
+	route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }),
+	async (req: Request, res: Response) => {
+		const { emoji_id, guild_id } = req.params;
 
-	await Emoji.delete({
-		id: emoji_id,
-		guild_id: guild_id
-	});
+		await Emoji.delete({
+			id: emoji_id,
+			guild_id: guild_id,
+		});
 
-	await emitEvent({
-		event: "GUILD_EMOJIS_UPDATE",
-		guild_id: guild_id,
-		data: {
+		await emitEvent({
+			event: "GUILD_EMOJIS_UPDATE",
 			guild_id: guild_id,
-			emojis: await Emoji.find({ where: { guild_id: guild_id } })
-		}
-	} as GuildEmojisUpdateEvent);
+			data: {
+				guild_id: guild_id,
+				emojis: await Emoji.find({ where: { guild_id: guild_id } }),
+			},
+		} as GuildEmojisUpdateEvent);
 
-	res.sendStatus(204);
-});
+		res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts
index afeb0938..715a3835 100644
--- a/src/api/routes/guilds/#guild_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/index.ts
@@ -1,5 +1,15 @@
 import { Request, Response, Router } from "express";
-import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member, GuildCreateSchema } from "@fosscord/util";
+import {
+	DiscordApiErrors,
+	emitEvent,
+	getPermission,
+	getRights,
+	Guild,
+	GuildUpdateEvent,
+	handleFile,
+	Member,
+	GuildCreateSchema,
+} from "@fosscord/util";
 import { HTTPError } from "lambert-server";
 import { route } from "@fosscord/api";
 
@@ -26,9 +36,13 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 
 	const [guild, member] = await Promise.all([
 		Guild.findOneOrFail({ where: { id: guild_id } }),
-		Member.findOne({ where: { guild_id: guild_id, id: req.user_id } })
+		Member.findOne({ where: { guild_id: guild_id, id: req.user_id } }),
 	]);
-	if (!member) throw new HTTPError("You are not a member of the guild you are trying to access", 401);
+	if (!member)
+		throw new HTTPError(
+			"You are not a member of the guild you are trying to access",
+			401,
+		);
 
 	// @ts-ignore
 	guild.joined_at = member?.joined_at;
@@ -36,39 +50,57 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	return res.send(guild);
 });
 
-router.patch("/", route({ body: "GuildUpdateSchema" }), async (req: Request, res: Response) => {
-	const body = req.body as GuildUpdateSchema;
-	const { guild_id } = req.params;
-
-
-	const rights = await getRights(req.user_id);
-	const permission = await getPermission(req.user_id, guild_id);
-
-	if (!rights.has("MANAGE_GUILDS") || !permission.has("MANAGE_GUILD"))
-		throw DiscordApiErrors.MISSING_PERMISSIONS.withParams("MANAGE_GUILD");
-
-	// TODO: guild update check image
-
-	if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon);
-	if (body.banner) body.banner = await handleFile(`/banners/${guild_id}`, body.banner);
-	if (body.splash) body.splash = await handleFile(`/splashes/${guild_id}`, body.splash);
-
-	var guild = await Guild.findOneOrFail({
-		where: { id: guild_id },
-		relations: ["emojis", "roles", "stickers"]
-	});
-	// TODO: check if body ids are valid
-	guild.assign(body);
-
-	const data = guild.toJSON();
-	// TODO: guild hashes
-	// TODO: fix vanity_url_code, template_id
-	delete data.vanity_url_code;
-	delete data.template_id;
-
-	await Promise.all([guild.save(), emitEvent({ event: "GUILD_UPDATE", data, guild_id } as GuildUpdateEvent)]);
-
-	return res.json(data);
-});
+router.patch(
+	"/",
+	route({ body: "GuildUpdateSchema" }),
+	async (req: Request, res: Response) => {
+		const body = req.body as GuildUpdateSchema;
+		const { guild_id } = req.params;
+
+		const rights = await getRights(req.user_id);
+		const permission = await getPermission(req.user_id, guild_id);
+
+		if (!rights.has("MANAGE_GUILDS") || !permission.has("MANAGE_GUILD"))
+			throw DiscordApiErrors.MISSING_PERMISSIONS.withParams(
+				"MANAGE_GUILD",
+			);
+
+		// TODO: guild update check image
+
+		if (body.icon)
+			body.icon = await handleFile(`/icons/${guild_id}`, body.icon);
+		if (body.banner)
+			body.banner = await handleFile(`/banners/${guild_id}`, body.banner);
+		if (body.splash)
+			body.splash = await handleFile(
+				`/splashes/${guild_id}`,
+				body.splash,
+			);
+
+		var guild = await Guild.findOneOrFail({
+			where: { id: guild_id },
+			relations: ["emojis", "roles", "stickers"],
+		});
+		// TODO: check if body ids are valid
+		guild.assign(body);
+
+		const data = guild.toJSON();
+		// TODO: guild hashes
+		// TODO: fix vanity_url_code, template_id
+		delete data.vanity_url_code;
+		delete data.template_id;
+
+		await Promise.all([
+			guild.save(),
+			emitEvent({
+				event: "GUILD_UPDATE",
+				data,
+				guild_id,
+			} as GuildUpdateEvent),
+		]);
+
+		return res.json(data);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/invites.ts b/src/api/routes/guilds/#guild_id/invites.ts
index b7534e31..4d033e9c 100644
--- a/src/api/routes/guilds/#guild_id/invites.ts
+++ b/src/api/routes/guilds/#guild_id/invites.ts
@@ -4,12 +4,19 @@ import { Request, Response, Router } from "express";
 
 const router = Router();
 
-router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
+router.get(
+	"/",
+	route({ permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
 
-	const invites = await Invite.find({ where: { guild_id }, relations: PublicInviteRelation });
+		const invites = await Invite.find({
+			where: { guild_id },
+			relations: PublicInviteRelation,
+		});
 
-	return res.json(invites);
-});
+		return res.json(invites);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/member-verification.ts b/src/api/routes/guilds/#guild_id/member-verification.ts
index 265a1b35..c2f946b2 100644
--- a/src/api/routes/guilds/#guild_id/member-verification.ts
+++ b/src/api/routes/guilds/#guild_id/member-verification.ts
@@ -2,12 +2,12 @@ import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 const router = Router();
 
-router.get("/",route({}), async (req: Request, res: Response) => {
+router.get("/", route({}), async (req: Request, res: Response) => {
 	// TODO: member verification
 
 	res.status(404).json({
 		message: "Unknown Guild Member Verification Form",
-		code: 10068
+		code: 10068,
 	});
 });
 
diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts
index 407619d3..2d867920 100644
--- a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts
@@ -1,5 +1,16 @@
 import { Request, Response, Router } from "express";
-import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Guild, MemberChangeSchema } from "@fosscord/util";
+import {
+	Member,
+	getPermission,
+	getRights,
+	Role,
+	GuildMemberUpdateEvent,
+	emitEvent,
+	Sticker,
+	Emoji,
+	Guild,
+	MemberChangeSchema,
+} from "@fosscord/util";
 import { route } from "@fosscord/api";
 
 const router = Router();
@@ -8,48 +19,63 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id, member_id } = req.params;
 	await Member.IsInGuildOrFail(req.user_id, guild_id);
 
-	const member = await Member.findOneOrFail({ where: { id: member_id, guild_id } });
+	const member = await Member.findOneOrFail({
+		where: { id: member_id, guild_id },
+	});
 
 	return res.json(member);
 });
 
-router.patch("/", route({ body: "MemberChangeSchema" }), async (req: Request, res: Response) => {
-	let { guild_id, member_id } = req.params;
-	if (member_id === "@me") member_id = req.user_id;
-	const body = req.body as MemberChangeSchema;
-
-	const member = await Member.findOneOrFail({ where: { id: member_id, guild_id }, relations: ["roles", "user"] });
-	const permission = await getPermission(req.user_id, guild_id);
-	const everyone = await Role.findOneOrFail({ where: { guild_id: guild_id, name: "@everyone", position: 0 } });
-
-	if (body.roles) {
-		permission.hasThrow("MANAGE_ROLES");
-
-		if (body.roles.indexOf(everyone.id) === -1) body.roles.push(everyone.id);
-		member.roles = body.roles.map((x) => Role.create({ id: x })); // foreign key constraint will fail if role doesn't exist
-	}
-
-	if ('nick' in body) {
-		permission.hasThrow(req.user_id == member.user.id ? "CHANGE_NICKNAME" : "MANAGE_NICKNAMES");
-		member.nick = body.nick?.trim() || undefined;
-	}
-
-	await member.save();
-
-	member.roles = member.roles.filter((x) => x.id !== everyone.id);
-
-	// do not use promise.all as we have to first write to db before emitting the event to catch errors
-	await emitEvent({
-		event: "GUILD_MEMBER_UPDATE",
-		guild_id,
-		data: { ...member, roles: member.roles.map((x) => x.id) }
-	} as GuildMemberUpdateEvent);
-
-	res.json(member);
-});
+router.patch(
+	"/",
+	route({ body: "MemberChangeSchema" }),
+	async (req: Request, res: Response) => {
+		let { guild_id, member_id } = req.params;
+		if (member_id === "@me") member_id = req.user_id;
+		const body = req.body as MemberChangeSchema;
+
+		const member = await Member.findOneOrFail({
+			where: { id: member_id, guild_id },
+			relations: ["roles", "user"],
+		});
+		const permission = await getPermission(req.user_id, guild_id);
+		const everyone = await Role.findOneOrFail({
+			where: { guild_id: guild_id, name: "@everyone", position: 0 },
+		});
+
+		if (body.roles) {
+			permission.hasThrow("MANAGE_ROLES");
+
+			if (body.roles.indexOf(everyone.id) === -1)
+				body.roles.push(everyone.id);
+			member.roles = body.roles.map((x) => Role.create({ id: x })); // foreign key constraint will fail if role doesn't exist
+		}
+
+		if ("nick" in body) {
+			permission.hasThrow(
+				req.user_id == member.user.id
+					? "CHANGE_NICKNAME"
+					: "MANAGE_NICKNAMES",
+			);
+			member.nick = body.nick?.trim() || undefined;
+		}
+
+		await member.save();
+
+		member.roles = member.roles.filter((x) => x.id !== everyone.id);
+
+		// do not use promise.all as we have to first write to db before emitting the event to catch errors
+		await emitEvent({
+			event: "GUILD_MEMBER_UPDATE",
+			guild_id,
+			data: { ...member, roles: member.roles.map((x) => x.id) },
+		} as GuildMemberUpdateEvent);
+
+		res.json(member);
+	},
+);
 
 router.put("/", route({}), async (req: Request, res: Response) => {
-
 	// TODO: Lurker mode
 
 	const rights = await getRights(req.user_id);
@@ -59,23 +85,23 @@ router.put("/", route({}), async (req: Request, res: Response) => {
 		member_id = req.user_id;
 		rights.hasThrow("JOIN_GUILDS");
 	} else {
-		// TODO: join others by controller	
+		// TODO: join others by controller
 	}
 
 	var guild = await Guild.findOneOrFail({
-		where: { id: guild_id }
+		where: { id: guild_id },
 	});
 
 	var emoji = await Emoji.find({
-		where: { guild_id: guild_id }
+		where: { guild_id: guild_id },
 	});
 
 	var roles = await Role.find({
-		where: { guild_id: guild_id }
+		where: { guild_id: guild_id },
 	});
 
 	var stickers = await Sticker.find({
-		where: { guild_id: guild_id }
+		where: { guild_id: guild_id },
 	});
 
 	await Member.addToGuild(member_id, guild_id);
diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts
index edd47605..20443821 100644
--- a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts
+++ b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts
@@ -4,19 +4,23 @@ import { Request, Response, Router } from "express";
 
 const router = Router();
 
-router.patch("/", route({ body: "MemberNickChangeSchema" }), async (req: Request, res: Response) => {
-	var { guild_id, member_id } = req.params;
-	var permissionString: PermissionResolvable = "MANAGE_NICKNAMES";
-	if (member_id === "@me") {
-		member_id = req.user_id;
-		permissionString = "CHANGE_NICKNAME";
-	}
+router.patch(
+	"/",
+	route({ body: "MemberNickChangeSchema" }),
+	async (req: Request, res: Response) => {
+		var { guild_id, member_id } = req.params;
+		var permissionString: PermissionResolvable = "MANAGE_NICKNAMES";
+		if (member_id === "@me") {
+			member_id = req.user_id;
+			permissionString = "CHANGE_NICKNAME";
+		}
 
-	const perms = await getPermission(req.user_id, guild_id);
-	perms.hasThrow(permissionString);
+		const perms = await getPermission(req.user_id, guild_id);
+		perms.hasThrow(permissionString);
 
-	await Member.changeNickname(member_id, guild_id, req.body.nick);
-	res.status(200).send();
-});
+		await Member.changeNickname(member_id, guild_id, req.body.nick);
+		res.status(200).send();
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts
index 8f5ca7ba..c0383912 100644
--- a/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts
@@ -4,18 +4,26 @@ import { Request, Response, Router } from "express";
 
 const router = Router();
 
-router.delete("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
-	const { guild_id, role_id, member_id } = req.params;
+router.delete(
+	"/",
+	route({ permission: "MANAGE_ROLES" }),
+	async (req: Request, res: Response) => {
+		const { guild_id, role_id, member_id } = req.params;
 
-	await Member.removeRole(member_id, guild_id, role_id);
-	res.sendStatus(204);
-});
+		await Member.removeRole(member_id, guild_id, role_id);
+		res.sendStatus(204);
+	},
+);
 
-router.put("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
-	const { guild_id, role_id, member_id } = req.params;
+router.put(
+	"/",
+	route({ permission: "MANAGE_ROLES" }),
+	async (req: Request, res: Response) => {
+		const { guild_id, role_id, member_id } = req.params;
 
-	await Member.addRole(member_id, guild_id, role_id);
-	res.sendStatus(204);
-});
+		await Member.addRole(member_id, guild_id, role_id);
+		res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/members/index.ts b/src/api/routes/guilds/#guild_id/members/index.ts
index b730a4e7..b516b9e9 100644
--- a/src/api/routes/guilds/#guild_id/members/index.ts
+++ b/src/api/routes/guilds/#guild_id/members/index.ts
@@ -12,7 +12,8 @@ const router = Router();
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 	const limit = Number(req.query.limit) || 1;
-	if (limit > 1000 || limit < 1) throw new HTTPError("Limit must be between 1 and 1000");
+	if (limit > 1000 || limit < 1)
+		throw new HTTPError("Limit must be between 1 and 1000");
 	const after = `${req.query.after}`;
 	const query = after ? { id: MoreThan(after) } : {};
 
@@ -22,7 +23,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 		where: { guild_id, ...query },
 		select: PublicMemberProjection,
 		take: limit,
-		order: { id: "ASC" }
+		order: { id: "ASC" },
 	});
 
 	return res.json(members);
diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts
index a7516ebd..f2d8087e 100644
--- a/src/api/routes/guilds/#guild_id/messages/search.ts
+++ b/src/api/routes/guilds/#guild_id/messages/search.ts
@@ -10,36 +10,62 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	const {
 		channel_id,
 		content,
-		include_nsfw,		// TODO
+		include_nsfw, // TODO
 		offset,
 		sort_order,
-		sort_by,			// TODO: Handle 'relevance'
+		sort_by, // TODO: Handle 'relevance'
 		limit,
 		author_id,
 	} = req.query;
 
 	const parsedLimit = Number(limit) || 50;
-	if (parsedLimit < 1 || parsedLimit > 100) throw new HTTPError("limit must be between 1 and 100", 422);
+	if (parsedLimit < 1 || parsedLimit > 100)
+		throw new HTTPError("limit must be between 1 and 100", 422);
 
 	if (sort_order) {
-		if (typeof sort_order != "string"
-			|| ["desc", "asc"].indexOf(sort_order) == -1)
-			throw FieldErrors({ sort_order: { message: "Value must be one of ('desc', 'asc').", code: "BASE_TYPE_CHOICES" } }); // todo this is wrong
+		if (
+			typeof sort_order != "string" ||
+			["desc", "asc"].indexOf(sort_order) == -1
+		)
+			throw FieldErrors({
+				sort_order: {
+					message: "Value must be one of ('desc', 'asc').",
+					code: "BASE_TYPE_CHOICES",
+				},
+			}); // todo this is wrong
 	}
 
-	const permissions = await getPermission(req.user_id, req.params.guild_id, channel_id as string);
+	const permissions = await getPermission(
+		req.user_id,
+		req.params.guild_id,
+		channel_id as string,
+	);
 	permissions.hasThrow("VIEW_CHANNEL");
-	if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json({ messages: [], total_results: 0 });
+	if (!permissions.has("READ_MESSAGE_HISTORY"))
+		return res.json({ messages: [], total_results: 0 });
 
 	var query: FindManyOptions<Message> = {
-		order: { timestamp: sort_order ? sort_order.toUpperCase() as "ASC" | "DESC" : "DESC" },
+		order: {
+			timestamp: sort_order
+				? (sort_order.toUpperCase() as "ASC" | "DESC")
+				: "DESC",
+		},
 		take: parsedLimit || 0,
 		where: {
 			guild: {
 				id: req.params.guild_id,
 			},
 		},
-		relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"],
+		relations: [
+			"author",
+			"webhook",
+			"application",
+			"mentions",
+			"mention_roles",
+			"mention_channels",
+			"sticker_items",
+			"attachments",
+		],
 		skip: offset ? Number(offset) : 0,
 	};
 	//@ts-ignore
@@ -51,32 +77,34 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 
 	const messages: Message[] = await Message.find(query);
 
-	const messagesDto = messages.map(x => [{
-		id: x.id,
-		type: x.type,
-		content: x.content,
-		channel_id: x.channel_id,
-		author: {
-			id: x.author?.id,
-			username: x.author?.username,
-			avatar: x.author?.avatar,
-			avatar_decoration: null,
-			discriminator: x.author?.discriminator,
-			public_flags: x.author?.public_flags,
+	const messagesDto = messages.map((x) => [
+		{
+			id: x.id,
+			type: x.type,
+			content: x.content,
+			channel_id: x.channel_id,
+			author: {
+				id: x.author?.id,
+				username: x.author?.username,
+				avatar: x.author?.avatar,
+				avatar_decoration: null,
+				discriminator: x.author?.discriminator,
+				public_flags: x.author?.public_flags,
+			},
+			attachments: x.attachments,
+			embeds: x.embeds,
+			mentions: x.mentions,
+			mention_roles: x.mention_roles,
+			pinned: x.pinned,
+			mention_everyone: x.mention_everyone,
+			tts: x.tts,
+			timestamp: x.timestamp,
+			edited_timestamp: x.edited_timestamp,
+			flags: x.flags,
+			components: x.components,
+			hit: true,
 		},
-		attachments: x.attachments,
-		embeds: x.embeds,
-		mentions: x.mentions,
-		mention_roles: x.mention_roles,
-		pinned: x.pinned,
-		mention_everyone: x.mention_everyone,
-		tts: x.tts,
-		timestamp: x.timestamp,
-		edited_timestamp: x.edited_timestamp,
-		flags: x.flags,
-		components: x.components,
-		hit: true,
-	}]);
+	]);
 
 	return res.json({
 		messages: messagesDto,
@@ -84,4 +112,4 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	});
 });
 
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/guilds/#guild_id/prune.ts b/src/api/routes/guilds/#guild_id/prune.ts
index 2e674349..d11244b1 100644
--- a/src/api/routes/guilds/#guild_id/prune.ts
+++ b/src/api/routes/guilds/#guild_id/prune.ts
@@ -5,7 +5,12 @@ import { route } from "@fosscord/api";
 const router = Router();
 
 //Returns all inactive members, respecting role hierarchy
-export const inactiveMembers = async (guild_id: string, user_id: string, days: number, roles: string[] = []) => {
+export const inactiveMembers = async (
+	guild_id: string,
+	user_id: string,
+	days: number,
+	roles: string[] = [],
+) => {
 	var date = new Date();
 	date.setDate(date.getDate() - days);
 	//Snowflake should have `generateFromTime` method? Or similar?
@@ -19,21 +24,27 @@ export const inactiveMembers = async (guild_id: string, user_id: string, days: n
 		where: [
 			{
 				guild_id,
-				last_message_id: LessThan(minId.toString())
+				last_message_id: LessThan(minId.toString()),
 			},
 			{
-				last_message_id: IsNull()
-			}
+				last_message_id: IsNull(),
+			},
 		],
-		relations: ["roles"]
+		relations: ["roles"],
 	});
 	console.log(members);
 	if (!members.length) return [];
 
 	//I'm sure I can do this in the above db query ( and it would probably be better to do so ), but oh well.
-	if (roles.length && members.length) members = members.filter((user) => user.roles?.some((role) => roles.includes(role.id)));
-
-	const me = await Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["roles"] });
+	if (roles.length && members.length)
+		members = members.filter((user) =>
+			user.roles?.some((role) => roles.includes(role.id)),
+		);
+
+	const me = await Member.findOneOrFail({
+		where: { id: user_id, guild_id },
+		relations: ["roles"],
+	});
 	const myHighestRole = Math.max(...(me.roles?.map((x) => x.position) || []));
 
 	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
@@ -44,8 +55,8 @@ export const inactiveMembers = async (guild_id: string, user_id: string, days: n
 			member.roles?.some(
 				(role) =>
 					role.position < myHighestRole || //roles higher than me can't be kicked
-					me.id === guild.owner_id //owner can kick anyone
-			)
+					me.id === guild.owner_id, //owner can kick anyone
+			),
 	);
 
 	return members;
@@ -57,23 +68,39 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	var roles = req.query.include_roles;
 	if (typeof roles === "string") roles = [roles]; //express will return array otherwise
 
-	const members = await inactiveMembers(req.params.guild_id, req.user_id, days, roles as string[]);
+	const members = await inactiveMembers(
+		req.params.guild_id,
+		req.user_id,
+		days,
+		roles as string[],
+	);
 
 	res.send({ pruned: members.length });
 });
 
-router.post("/", route({ permission: "KICK_MEMBERS", right: "KICK_BAN_MEMBERS" }), async (req: Request, res: Response) => {
-	const days = parseInt(req.body.days);
-
-	var roles = req.query.include_roles;
-	if (typeof roles === "string") roles = [roles];
-
-	const { guild_id } = req.params;
-	const members = await inactiveMembers(guild_id, req.user_id, days, roles as string[]);
-
-	await Promise.all(members.map((x) => Member.removeFromGuild(x.id, guild_id)));
-
-	res.send({ purged: members.length });
-});
+router.post(
+	"/",
+	route({ permission: "KICK_MEMBERS", right: "KICK_BAN_MEMBERS" }),
+	async (req: Request, res: Response) => {
+		const days = parseInt(req.body.days);
+
+		var roles = req.query.include_roles;
+		if (typeof roles === "string") roles = [roles];
+
+		const { guild_id } = req.params;
+		const members = await inactiveMembers(
+			guild_id,
+			req.user_id,
+			days,
+			roles as string[],
+		);
+
+		await Promise.all(
+			members.map((x) => Member.removeFromGuild(x.id, guild_id)),
+		);
+
+		res.send({ purged: members.length });
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/regions.ts b/src/api/routes/guilds/#guild_id/regions.ts
index 308d5ee5..0b275ea4 100644
--- a/src/api/routes/guilds/#guild_id/regions.ts
+++ b/src/api/routes/guilds/#guild_id/regions.ts
@@ -9,7 +9,12 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
 	//TODO we should use an enum for guild's features and not hardcoded strings
-	return res.json(await getVoiceRegions(getIpAdress(req), guild.features.includes("VIP_REGIONS")));
+	return res.json(
+		await getVoiceRegions(
+			getIpAdress(req),
+			guild.features.includes("VIP_REGIONS"),
+		),
+	);
 });
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts
index 87cf5261..e274e3d0 100644
--- a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts
@@ -1,5 +1,13 @@
 import { Router, Request, Response } from "express";
-import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile, RoleModifySchema } from "@fosscord/util";
+import {
+	Role,
+	Member,
+	GuildRoleUpdateEvent,
+	GuildRoleDeleteEvent,
+	emitEvent,
+	handleFile,
+	RoleModifySchema,
+} from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { HTTPError } from "lambert-server";
 
@@ -12,57 +20,72 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	return res.json(role);
 });
 
-router.delete("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
-	const { guild_id, role_id } = req.params;
-	if (role_id === guild_id) throw new HTTPError("You can't delete the @everyone role");
+router.delete(
+	"/",
+	route({ permission: "MANAGE_ROLES" }),
+	async (req: Request, res: Response) => {
+		const { guild_id, role_id } = req.params;
+		if (role_id === guild_id)
+			throw new HTTPError("You can't delete the @everyone role");
 
-	await Promise.all([
-		Role.delete({
-			id: role_id,
-			guild_id: guild_id
-		}),
-		emitEvent({
-			event: "GUILD_ROLE_DELETE",
-			guild_id,
-			data: {
+		await Promise.all([
+			Role.delete({
+				id: role_id,
+				guild_id: guild_id,
+			}),
+			emitEvent({
+				event: "GUILD_ROLE_DELETE",
 				guild_id,
-				role_id
-			}
-		} as GuildRoleDeleteEvent)
-	]);
+				data: {
+					guild_id,
+					role_id,
+				},
+			} as GuildRoleDeleteEvent),
+		]);
 
-	res.sendStatus(204);
-});
+		res.sendStatus(204);
+	},
+);
 
 // TODO: check role hierarchy
 
-router.patch("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
-	const { role_id, guild_id } = req.params;
-	const body = req.body as RoleModifySchema;
+router.patch(
+	"/",
+	route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }),
+	async (req: Request, res: Response) => {
+		const { role_id, guild_id } = req.params;
+		const body = req.body as RoleModifySchema;
 
-	if (body.icon && body.icon.length) body.icon = await handleFile(`/role-icons/${role_id}`, body.icon as string);
-	else body.icon = undefined;
+		if (body.icon && body.icon.length)
+			body.icon = await handleFile(
+				`/role-icons/${role_id}`,
+				body.icon as string,
+			);
+		else body.icon = undefined;
 
-	const role = Role.create({
-		...body,
-		id: role_id,
-		guild_id,
-		permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0"))
-	});
-
-	await Promise.all([
-		role.save(),
-		emitEvent({
-			event: "GUILD_ROLE_UPDATE",
+		const role = Role.create({
+			...body,
+			id: role_id,
 			guild_id,
-			data: {
+			permissions: String(
+				req.permission!.bitfield & BigInt(body.permissions || "0"),
+			),
+		});
+
+		await Promise.all([
+			role.save(),
+			emitEvent({
+				event: "GUILD_ROLE_UPDATE",
 				guild_id,
-				role
-			}
-		} as GuildRoleUpdateEvent)
-	]);
+				data: {
+					guild_id,
+					role,
+				},
+			} as GuildRoleUpdateEvent),
+		]);
 
-	res.json(role);
-});
+		res.json(role);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts
index c5a86400..e3c7373e 100644
--- a/src/api/routes/guilds/#guild_id/roles/index.ts
+++ b/src/api/routes/guilds/#guild_id/roles/index.ts
@@ -29,70 +29,87 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	return res.json(roles);
 });
 
-router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
-	const guild_id = req.params.guild_id;
-	const body = req.body as RoleModifySchema;
-
-	const role_count = await Role.count({ where: { guild_id } });
-	const { maxRoles } = Config.get().limits.guild;
-
-	if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles);
-
-	const role = Role.create({
-		// values before ...body are default and can be overriden
-		position: 0,
-		hoist: false,
-		color: 0,
-		mentionable: false,
-		...body,
-		guild_id: guild_id,
-		managed: false,
-		permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0")),
-		tags: undefined,
-		icon: undefined,
-		unicode_emoji: undefined
-	});
-
-	await Promise.all([
-		role.save(),
-		emitEvent({
-			event: "GUILD_ROLE_CREATE",
-			guild_id,
-			data: {
-				guild_id,
-				role: role
-			}
-		} as GuildRoleCreateEvent)
-	]);
-
-	res.json(role);
-});
-
-router.patch("/", route({ body: "RolePositionUpdateSchema" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const body = req.body as RolePositionUpdateSchema;
-
-	const perms = await getPermission(req.user_id, guild_id);
-	perms.hasThrow("MANAGE_ROLES");
-
-	await Promise.all(body.map(async (x) => Role.update({ guild_id, id: x.id }, { position: x.position })));
-
-	const roles = await Role.find({ where: body.map((x) => ({ id: x.id, guild_id })) });
-
-	await Promise.all(
-		roles.map((x) =>
+router.post(
+	"/",
+	route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }),
+	async (req: Request, res: Response) => {
+		const guild_id = req.params.guild_id;
+		const body = req.body as RoleModifySchema;
+
+		const role_count = await Role.count({ where: { guild_id } });
+		const { maxRoles } = Config.get().limits.guild;
+
+		if (role_count > maxRoles)
+			throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles);
+
+		const role = Role.create({
+			// values before ...body are default and can be overriden
+			position: 0,
+			hoist: false,
+			color: 0,
+			mentionable: false,
+			...body,
+			guild_id: guild_id,
+			managed: false,
+			permissions: String(
+				req.permission!.bitfield & BigInt(body.permissions || "0"),
+			),
+			tags: undefined,
+			icon: undefined,
+			unicode_emoji: undefined,
+		});
+
+		await Promise.all([
+			role.save(),
 			emitEvent({
-				event: "GUILD_ROLE_UPDATE",
+				event: "GUILD_ROLE_CREATE",
 				guild_id,
 				data: {
 					guild_id,
-					role: x
-				}
-			} as GuildRoleUpdateEvent)
-		)
-	);
-
-	res.json(roles);
-});
+					role: role,
+				},
+			} as GuildRoleCreateEvent),
+		]);
+
+		res.json(role);
+	},
+);
+
+router.patch(
+	"/",
+	route({ body: "RolePositionUpdateSchema" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const body = req.body as RolePositionUpdateSchema;
+
+		const perms = await getPermission(req.user_id, guild_id);
+		perms.hasThrow("MANAGE_ROLES");
+
+		await Promise.all(
+			body.map(async (x) =>
+				Role.update({ guild_id, id: x.id }, { position: x.position }),
+			),
+		);
+
+		const roles = await Role.find({
+			where: body.map((x) => ({ id: x.id, guild_id })),
+		});
+
+		await Promise.all(
+			roles.map((x) =>
+				emitEvent({
+					event: "GUILD_ROLE_UPDATE",
+					guild_id,
+					data: {
+						guild_id,
+						role: x,
+					},
+				} as GuildRoleUpdateEvent),
+			),
+		);
+
+		res.json(roles);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/stickers.ts b/src/api/routes/guilds/#guild_id/stickers.ts
index fc0f49ab..3b1f5f8e 100644
--- a/src/api/routes/guilds/#guild_id/stickers.ts
+++ b/src/api/routes/guilds/#guild_id/stickers.ts
@@ -26,15 +26,18 @@ const bodyParser = multer({
 	limits: {
 		fileSize: 1024 * 1024 * 100,
 		fields: 10,
-		files: 1
+		files: 1,
 	},
-	storage: multer.memoryStorage()
+	storage: multer.memoryStorage(),
 }).single("file");
 
 router.post(
 	"/",
 	bodyParser,
-	route({ permission: "MANAGE_EMOJIS_AND_STICKERS", body: "ModifyGuildStickerSchema" }),
+	route({
+		permission: "MANAGE_EMOJIS_AND_STICKERS",
+		body: "ModifyGuildStickerSchema",
+	}),
 	async (req: Request, res: Response) => {
 		if (!req.file) throw new HTTPError("missing file");
 
@@ -49,15 +52,15 @@ router.post(
 				id,
 				type: StickerType.GUILD,
 				format_type: getStickerFormat(req.file.mimetype),
-				available: true
+				available: true,
 			}).save(),
-			uploadFile(`/stickers/${id}`, req.file)
+			uploadFile(`/stickers/${id}`, req.file),
 		]);
 
 		await sendStickerUpdateEvent(guild_id);
 
 		res.json(sticker);
-	}
+	},
 );
 
 export function getStickerFormat(mime_type: string) {
@@ -71,7 +74,9 @@ export function getStickerFormat(mime_type: string) {
 		case "image/gif":
 			return StickerFormatType.GIF;
 		default:
-			throw new HTTPError("invalid sticker format: must be png, apng or lottie");
+			throw new HTTPError(
+				"invalid sticker format: must be png, apng or lottie",
+			);
 	}
 }
 
@@ -79,21 +84,30 @@ router.get("/:sticker_id", route({}), async (req: Request, res: Response) => {
 	const { guild_id, sticker_id } = req.params;
 	await Member.IsInGuildOrFail(req.user_id, guild_id);
 
-	res.json(await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id } }));
+	res.json(
+		await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id } }),
+	);
 });
 
 router.patch(
 	"/:sticker_id",
-	route({ body: "ModifyGuildStickerSchema", permission: "MANAGE_EMOJIS_AND_STICKERS" }),
+	route({
+		body: "ModifyGuildStickerSchema",
+		permission: "MANAGE_EMOJIS_AND_STICKERS",
+	}),
 	async (req: Request, res: Response) => {
 		const { guild_id, sticker_id } = req.params;
 		const body = req.body as ModifyGuildStickerSchema;
 
-		const sticker = await Sticker.create({ ...body, guild_id, id: sticker_id }).save();
+		const sticker = await Sticker.create({
+			...body,
+			guild_id,
+			id: sticker_id,
+		}).save();
 		await sendStickerUpdateEvent(guild_id);
 
 		return res.json(sticker);
-	}
+	},
 );
 
 async function sendStickerUpdateEvent(guild_id: string) {
@@ -102,18 +116,22 @@ async function sendStickerUpdateEvent(guild_id: string) {
 		guild_id: guild_id,
 		data: {
 			guild_id: guild_id,
-			stickers: await Sticker.find({ where: { guild_id: guild_id } })
-		}
+			stickers: await Sticker.find({ where: { guild_id: guild_id } }),
+		},
 	} as GuildStickersUpdateEvent);
 }
 
-router.delete("/:sticker_id", route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }), async (req: Request, res: Response) => {
-	const { guild_id, sticker_id } = req.params;
+router.delete(
+	"/:sticker_id",
+	route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }),
+	async (req: Request, res: Response) => {
+		const { guild_id, sticker_id } = req.params;
 
-	await Sticker.delete({ guild_id, id: sticker_id });
-	await sendStickerUpdateEvent(guild_id);
+		await Sticker.delete({ guild_id, id: sticker_id });
+		await sendStickerUpdateEvent(guild_id);
 
-	return res.sendStatus(204);
-});
+		return res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/templates.ts b/src/api/routes/guilds/#guild_id/templates.ts
index 628321f5..3b5eddaa 100644
--- a/src/api/routes/guilds/#guild_id/templates.ts
+++ b/src/api/routes/guilds/#guild_id/templates.ts
@@ -20,63 +20,97 @@ const TemplateGuildProjection: (keyof Guild)[] = [
 	"afk_channel_id",
 	"system_channel_id",
 	"system_channel_flags",
-	"icon"
+	"icon",
 ];
 
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 
-	var templates = await Template.find({ where: { source_guild_id: guild_id } });
-
-	return res.json(templates);
-});
-
-router.post("/", route({ body: "TemplateCreateSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection });
-	const exists = await Template.findOneOrFail({ where: { id: guild_id } }).catch((e) => { });
-	if (exists) throw new HTTPError("Template already exists", 400);
-
-	const template = await Template.create({
-		...req.body,
-		code: generateCode(),
-		creator_id: req.user_id,
-		created_at: new Date(),
-		updated_at: new Date(),
-		source_guild_id: guild_id,
-		serialized_source_guild: guild
-	}).save();
-
-	res.json(template);
-});
-
-router.delete("/:code", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { code, guild_id } = req.params;
-
-	const template = await Template.delete({
-		code,
-		source_guild_id: guild_id
+	var templates = await Template.find({
+		where: { source_guild_id: guild_id },
 	});
 
-	res.json(template);
-});
-
-router.put("/:code", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { code, guild_id } = req.params;
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection });
-
-	const template = await Template.create({ code, serialized_source_guild: guild }).save();
-
-	res.json(template);
+	return res.json(templates);
 });
 
-router.patch("/:code", route({ body: "TemplateModifySchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { code, guild_id } = req.params;
-	const { name, description } = req.body;
-
-	const template = await Template.create({ code, name: name, description: description, source_guild_id: guild_id }).save();
-
-	res.json(template);
-});
+router.post(
+	"/",
+	route({ body: "TemplateCreateSchema", permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const guild = await Guild.findOneOrFail({
+			where: { id: guild_id },
+			select: TemplateGuildProjection,
+		});
+		const exists = await Template.findOneOrFail({
+			where: { id: guild_id },
+		}).catch((e) => {});
+		if (exists) throw new HTTPError("Template already exists", 400);
+
+		const template = await Template.create({
+			...req.body,
+			code: generateCode(),
+			creator_id: req.user_id,
+			created_at: new Date(),
+			updated_at: new Date(),
+			source_guild_id: guild_id,
+			serialized_source_guild: guild,
+		}).save();
+
+		res.json(template);
+	},
+);
+
+router.delete(
+	"/:code",
+	route({ permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { code, guild_id } = req.params;
+
+		const template = await Template.delete({
+			code,
+			source_guild_id: guild_id,
+		});
+
+		res.json(template);
+	},
+);
+
+router.put(
+	"/:code",
+	route({ permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { code, guild_id } = req.params;
+		const guild = await Guild.findOneOrFail({
+			where: { id: guild_id },
+			select: TemplateGuildProjection,
+		});
+
+		const template = await Template.create({
+			code,
+			serialized_source_guild: guild,
+		}).save();
+
+		res.json(template);
+	},
+);
+
+router.patch(
+	"/:code",
+	route({ body: "TemplateModifySchema", permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { code, guild_id } = req.params;
+		const { name, description } = req.body;
+
+		const template = await Template.create({
+			code,
+			name: name,
+			description: description,
+			source_guild_id: guild_id,
+		}).save();
+
+		res.json(template);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/vanity-url.ts b/src/api/routes/guilds/#guild_id/vanity-url.ts
index d1fe4726..9a96b066 100644
--- a/src/api/routes/guilds/#guild_id/vanity-url.ts
+++ b/src/api/routes/guilds/#guild_id/vanity-url.ts
@@ -1,4 +1,10 @@
-import { Channel, ChannelType, Guild, Invite, VanityUrlSchema } from "@fosscord/util";
+import {
+	Channel,
+	ChannelType,
+	Guild,
+	Invite,
+	VanityUrlSchema,
+} from "@fosscord/util";
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 import { HTTPError } from "lambert-server";
@@ -7,52 +13,70 @@ const router = Router();
 
 const InviteRegex = /\W/g;
 
-router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
-
-	if (!guild.features.includes("ALIASABLE_NAMES")) {
-		const invite = await Invite.findOne({ where: { guild_id: guild_id, vanity_url: true } });
-		if (!invite) return res.json({ code: null });
-
-		return res.json({ code: invite.code, uses: invite.uses });
-	} else {
-		const invite = await Invite.find({ where: { guild_id: guild_id, vanity_url: true } });
-		if (!invite || invite.length == 0) return res.json({ code: null });
-
-		return res.json(invite.map((x) => ({ code: x.code, uses: x.uses })));
-	}
-});
-
-router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const { guild_id } = req.params;
-	const body = req.body as VanityUrlSchema;
-	const code = body.code?.replace(InviteRegex, "");
-
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
-	if (!guild.features.includes("VANITY_URL")) throw new HTTPError("Your guild doesn't support vanity urls");
-
-	if (!code || code.length === 0) throw new HTTPError("Code cannot be null or empty");
-
-	const invite = await Invite.findOne({ where: { code } });
-	if (invite) throw new HTTPError("Invite already exists");
-
-	const { id } = await Channel.findOneOrFail({ where: { guild_id, type: ChannelType.GUILD_TEXT } });
-
-	await Invite.create({
-		vanity_url: true,
-		code: code,
-		temporary: false,
-		uses: 0,
-		max_uses: 0,
-		max_age: 0,
-		created_at: new Date(),
-		expires_at: new Date(),
-		guild_id: guild_id,
-		channel_id: id
-	}).save();
-
-	return res.json({ code: code });
-});
+router.get(
+	"/",
+	route({ permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
+
+		if (!guild.features.includes("ALIASABLE_NAMES")) {
+			const invite = await Invite.findOne({
+				where: { guild_id: guild_id, vanity_url: true },
+			});
+			if (!invite) return res.json({ code: null });
+
+			return res.json({ code: invite.code, uses: invite.uses });
+		} else {
+			const invite = await Invite.find({
+				where: { guild_id: guild_id, vanity_url: true },
+			});
+			if (!invite || invite.length == 0) return res.json({ code: null });
+
+			return res.json(
+				invite.map((x) => ({ code: x.code, uses: x.uses })),
+			);
+		}
+	},
+);
+
+router.patch(
+	"/",
+	route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const { guild_id } = req.params;
+		const body = req.body as VanityUrlSchema;
+		const code = body.code?.replace(InviteRegex, "");
+
+		const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
+		if (!guild.features.includes("VANITY_URL"))
+			throw new HTTPError("Your guild doesn't support vanity urls");
+
+		if (!code || code.length === 0)
+			throw new HTTPError("Code cannot be null or empty");
+
+		const invite = await Invite.findOne({ where: { code } });
+		if (invite) throw new HTTPError("Invite already exists");
+
+		const { id } = await Channel.findOneOrFail({
+			where: { guild_id, type: ChannelType.GUILD_TEXT },
+		});
+
+		await Invite.create({
+			vanity_url: true,
+			code: code,
+			temporary: false,
+			uses: 0,
+			max_uses: 0,
+			max_age: 0,
+			created_at: new Date(),
+			expires_at: new Date(),
+			guild_id: guild_id,
+			channel_id: id,
+		}).save();
+
+		return res.json({ code: code });
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts
index 006e997f..af03a07e 100644
--- a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts
@@ -1,52 +1,71 @@
-import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent, VoiceStateUpdateSchema } from "@fosscord/util";
+import {
+	Channel,
+	ChannelType,
+	DiscordApiErrors,
+	emitEvent,
+	getPermission,
+	VoiceState,
+	VoiceStateUpdateEvent,
+	VoiceStateUpdateSchema,
+} from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { Request, Response, Router } from "express";
 
 const router = Router();
 //TODO need more testing when community guild and voice stage channel are working
 
-router.patch("/", route({ body: "VoiceStateUpdateSchema" }), async (req: Request, res: Response) => {
-	const body = req.body as VoiceStateUpdateSchema;
-	var { guild_id, user_id } = req.params;
-	if (user_id === "@me") user_id = req.user_id;
+router.patch(
+	"/",
+	route({ body: "VoiceStateUpdateSchema" }),
+	async (req: Request, res: Response) => {
+		const body = req.body as VoiceStateUpdateSchema;
+		var { guild_id, user_id } = req.params;
+		if (user_id === "@me") user_id = req.user_id;
 
-	const perms = await getPermission(req.user_id, guild_id, body.channel_id);
+		const perms = await getPermission(
+			req.user_id,
+			guild_id,
+			body.channel_id,
+		);
 
-	/*
+		/*
 	From https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state
 	You must have the MUTE_MEMBERS permission to unsuppress others. You can always suppress yourself.
 	You must have the REQUEST_TO_SPEAK permission to request to speak. You can always clear your own request to speak.
 	 */
-	if (body.suppress && user_id !== req.user_id) {
-		perms.hasThrow("MUTE_MEMBERS");
-	}
-	if (!body.suppress) body.request_to_speak_timestamp = new Date();
-	if (body.request_to_speak_timestamp) perms.hasThrow("REQUEST_TO_SPEAK");
-
-	const voice_state = await VoiceState.findOne({
-		where: {
-			guild_id,
-			channel_id: body.channel_id,
-			user_id
+		if (body.suppress && user_id !== req.user_id) {
+			perms.hasThrow("MUTE_MEMBERS");
+		}
+		if (!body.suppress) body.request_to_speak_timestamp = new Date();
+		if (body.request_to_speak_timestamp) perms.hasThrow("REQUEST_TO_SPEAK");
+
+		const voice_state = await VoiceState.findOne({
+			where: {
+				guild_id,
+				channel_id: body.channel_id,
+				user_id,
+			},
+		});
+		if (!voice_state) throw DiscordApiErrors.UNKNOWN_VOICE_STATE;
+
+		voice_state.assign(body);
+		const channel = await Channel.findOneOrFail({
+			where: { guild_id, id: body.channel_id },
+		});
+		if (channel.type !== ChannelType.GUILD_STAGE_VOICE) {
+			throw DiscordApiErrors.CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE;
 		}
-	});
-	if (!voice_state) throw DiscordApiErrors.UNKNOWN_VOICE_STATE;
-
-	voice_state.assign(body);
-	const channel = await Channel.findOneOrFail({ where: { guild_id, id: body.channel_id } });
-	if (channel.type !== ChannelType.GUILD_STAGE_VOICE) {
-		throw DiscordApiErrors.CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE;
-	}
-
-	await Promise.all([
-		voice_state.save(),
-		emitEvent({
-			event: "VOICE_STATE_UPDATE",
-			data: voice_state,
-			guild_id
-		} as VoiceStateUpdateEvent)
-	]);
-	return res.sendStatus(204);
-});
+
+		await Promise.all([
+			voice_state.save(),
+			emitEvent({
+				event: "VOICE_STATE_UPDATE",
+				data: voice_state,
+				guild_id,
+			} as VoiceStateUpdateEvent),
+		]);
+		return res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/welcome-screen.ts b/src/api/routes/guilds/#guild_id/welcome-screen.ts
index 57da062d..80ab138b 100644
--- a/src/api/routes/guilds/#guild_id/welcome-screen.ts
+++ b/src/api/routes/guilds/#guild_id/welcome-screen.ts
@@ -14,20 +14,30 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json(guild.welcome_screen);
 });
 
-router.patch("/", route({ body: "GuildUpdateWelcomeScreenSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const guild_id = req.params.guild_id;
-	const body = req.body as GuildUpdateWelcomeScreenSchema;
-
-	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
-
-	if (!guild.welcome_screen.enabled) throw new HTTPError("Welcome screen disabled", 400);
-	if (body.welcome_channels) guild.welcome_screen.welcome_channels = body.welcome_channels; // TODO: check if they exist and are valid
-	if (body.description) guild.welcome_screen.description = body.description;
-	if (body.enabled != null) guild.welcome_screen.enabled = body.enabled;
-
-	await guild.save();
-
-	res.sendStatus(204);
-});
+router.patch(
+	"/",
+	route({
+		body: "GuildUpdateWelcomeScreenSchema",
+		permission: "MANAGE_GUILD",
+	}),
+	async (req: Request, res: Response) => {
+		const guild_id = req.params.guild_id;
+		const body = req.body as GuildUpdateWelcomeScreenSchema;
+
+		const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
+
+		if (!guild.welcome_screen.enabled)
+			throw new HTTPError("Welcome screen disabled", 400);
+		if (body.welcome_channels)
+			guild.welcome_screen.welcome_channels = body.welcome_channels; // TODO: check if they exist and are valid
+		if (body.description)
+			guild.welcome_screen.description = body.description;
+		if (body.enabled != null) guild.welcome_screen.enabled = body.enabled;
+
+		await guild.save();
+
+		res.sendStatus(204);
+	},
+);
 
 export default router;
diff --git a/src/api/routes/guilds/#guild_id/widget.json.ts b/src/api/routes/guilds/#guild_id/widget.json.ts
index be5bf23f..2c3124a2 100644
--- a/src/api/routes/guilds/#guild_id/widget.json.ts
+++ b/src/api/routes/guilds/#guild_id/widget.json.ts
@@ -1,5 +1,12 @@
 import { Request, Response, Router } from "express";
-import { Config, Permissions, Guild, Invite, Channel, Member } from "@fosscord/util";
+import {
+	Config,
+	Permissions,
+	Guild,
+	Invite,
+	Channel,
+	Member,
+} from "@fosscord/util";
 import { HTTPError } from "lambert-server";
 import { random, route } from "@fosscord/api";
 
@@ -21,7 +28,9 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	if (!guild.widget_enabled) throw new HTTPError("Widget Disabled", 404);
 
 	// Fetch existing widget invite for widget channel
-	var invite = await Invite.findOne({ where: { channel_id: guild.widget_channel_id } });
+	var invite = await Invite.findOne({
+		where: { channel_id: guild.widget_channel_id },
+	});
 
 	if (guild.widget_channel_id && !invite) {
 		// Create invite for channel if none exists
@@ -45,16 +54,24 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	// Fetch voice channels, and the @everyone permissions object
 	const channels = [] as any[];
 
-	(await Channel.find({ where: { guild_id: guild_id, type: 2 }, order: { position: "ASC" } })).filter((doc) => {
+	(
+		await Channel.find({
+			where: { guild_id: guild_id, type: 2 },
+			order: { position: "ASC" },
+		})
+	).filter((doc) => {
 		// Only return channels where @everyone has the CONNECT permission
 		if (
 			doc.permission_overwrites === undefined ||
-			Permissions.channelPermission(doc.permission_overwrites, Permissions.FLAGS.CONNECT) === Permissions.FLAGS.CONNECT
+			Permissions.channelPermission(
+				doc.permission_overwrites,
+				Permissions.FLAGS.CONNECT,
+			) === Permissions.FLAGS.CONNECT
 		) {
 			channels.push({
 				id: doc.id,
 				name: doc.name,
-				position: doc.position
+				position: doc.position,
 			});
 		}
 	});
@@ -70,7 +87,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 		instant_invite: invite?.code,
 		channels: channels,
 		members: members,
-		presence_count: guild.presence_count
+		presence_count: guild.presence_count,
 	};
 
 	res.set("Cache-Control", "public, max-age=300");
diff --git a/src/api/routes/guilds/#guild_id/widget.png.ts b/src/api/routes/guilds/#guild_id/widget.png.ts
index c17d511e..eaec8f07 100644
--- a/src/api/routes/guilds/#guild_id/widget.png.ts
+++ b/src/api/routes/guilds/#guild_id/widget.png.ts
@@ -24,8 +24,13 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 
 	// Fetch parameter
 	const style = req.query.style?.toString() || "shield";
-	if (!["shield", "banner1", "banner2", "banner3", "banner4"].includes(style)) {
-		throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400);
+	if (
+		!["shield", "banner1", "banner2", "banner3", "banner4"].includes(style)
+	) {
+		throw new HTTPError(
+			"Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').",
+			400,
+		);
 	}
 
 	// Setup canvas
@@ -34,7 +39,17 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	const sizeOf = require("image-size");
 
 	// TODO: Widget style templates need Fosscord branding
-	const source = path.join(__dirname, "..", "..", "..", "..", "..", "assets", "widget", `${style}.png`);
+	const source = path.join(
+		__dirname,
+		"..",
+		"..",
+		"..",
+		"..",
+		"..",
+		"assets",
+		"widget",
+		`${style}.png`,
+	);
 	if (!fs.existsSync(source)) {
 		throw new HTTPError("Widget template does not exist.", 400);
 	}
@@ -50,30 +65,68 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	switch (style) {
 		case "shield":
 			ctx.textAlign = "center";
-			await drawText(ctx, 73, 13, "#FFFFFF", "thin 10px Verdana", presence);
+			await drawText(
+				ctx,
+				73,
+				13,
+				"#FFFFFF",
+				"thin 10px Verdana",
+				presence,
+			);
 			break;
 		case "banner1":
 			if (icon) await drawIcon(ctx, 20, 27, 50, icon);
 			await drawText(ctx, 83, 51, "#FFFFFF", "12px Verdana", name, 22);
-			await drawText(ctx, 83, 66, "#C9D2F0FF", "thin 11px Verdana", presence);
+			await drawText(
+				ctx,
+				83,
+				66,
+				"#C9D2F0FF",
+				"thin 11px Verdana",
+				presence,
+			);
 			break;
 		case "banner2":
 			if (icon) await drawIcon(ctx, 13, 19, 36, icon);
 			await drawText(ctx, 62, 34, "#FFFFFF", "12px Verdana", name, 15);
-			await drawText(ctx, 62, 49, "#C9D2F0FF", "thin 11px Verdana", presence);
+			await drawText(
+				ctx,
+				62,
+				49,
+				"#C9D2F0FF",
+				"thin 11px Verdana",
+				presence,
+			);
 			break;
 		case "banner3":
 			if (icon) await drawIcon(ctx, 20, 20, 50, icon);
 			await drawText(ctx, 83, 44, "#FFFFFF", "12px Verdana", name, 27);
-			await drawText(ctx, 83, 58, "#C9D2F0FF", "thin 11px Verdana", presence);
+			await drawText(
+				ctx,
+				83,
+				58,
+				"#C9D2F0FF",
+				"thin 11px Verdana",
+				presence,
+			);
 			break;
 		case "banner4":
 			if (icon) await drawIcon(ctx, 21, 136, 50, icon);
 			await drawText(ctx, 84, 156, "#FFFFFF", "13px Verdana", name, 27);
-			await drawText(ctx, 84, 171, "#C9D2F0FF", "thin 12px Verdana", presence);
+			await drawText(
+				ctx,
+				84,
+				171,
+				"#C9D2F0FF",
+				"thin 12px Verdana",
+				presence,
+			);
 			break;
 		default:
-			throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400);
+			throw new HTTPError(
+				"Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').",
+				400,
+			);
 	}
 
 	// Return final image
@@ -83,7 +136,13 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 	return res.send(buffer);
 });
 
-async function drawIcon(canvas: any, x: number, y: number, scale: number, icon: string) {
+async function drawIcon(
+	canvas: any,
+	x: number,
+	y: number,
+	scale: number,
+	icon: string,
+) {
 	// @ts-ignore
 	const img = new require("canvas").Image();
 	img.src = icon;
@@ -101,10 +160,19 @@ async function drawIcon(canvas: any, x: number, y: number, scale: number, icon:
 	canvas.restore();
 }
 
-async function drawText(canvas: any, x: number, y: number, color: string, font: string, text: string, maxcharacters?: number) {
+async function drawText(
+	canvas: any,
+	x: number,
+	y: number,
+	color: string,
+	font: string,
+	text: string,
+	maxcharacters?: number,
+) {
 	canvas.fillStyle = color;
 	canvas.font = font;
-	if (text.length > (maxcharacters || 0) && maxcharacters) text = text.slice(0, maxcharacters) + "...";
+	if (text.length > (maxcharacters || 0) && maxcharacters)
+		text = text.slice(0, maxcharacters) + "...";
 	canvas.fillText(text, x, y);
 }
 
diff --git a/src/api/routes/guilds/#guild_id/widget.ts b/src/api/routes/guilds/#guild_id/widget.ts
index dbb4cc0c..108339e1 100644
--- a/src/api/routes/guilds/#guild_id/widget.ts
+++ b/src/api/routes/guilds/#guild_id/widget.ts
@@ -10,18 +10,31 @@ router.get("/", route({}), async (req: Request, res: Response) => {
 
 	const guild = await Guild.findOneOrFail({ where: { id: guild_id } });
 
-	return res.json({ enabled: guild.widget_enabled || false, channel_id: guild.widget_channel_id || null });
+	return res.json({
+		enabled: guild.widget_enabled || false,
+		channel_id: guild.widget_channel_id || null,
+	});
 });
 
 // https://discord.com/developers/docs/resources/guild#modify-guild-widget
-router.patch("/", route({ body: "WidgetModifySchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
-	const body = req.body as WidgetModifySchema;
-	const { guild_id } = req.params;
-
-	await Guild.update({ id: guild_id }, { widget_enabled: body.enabled, widget_channel_id: body.channel_id });
-	// Widget invite for the widget_channel_id gets created as part of the /guilds/{guild.id}/widget.json request
-
-	return res.json(body);
-});
+router.patch(
+	"/",
+	route({ body: "WidgetModifySchema", permission: "MANAGE_GUILD" }),
+	async (req: Request, res: Response) => {
+		const body = req.body as WidgetModifySchema;
+		const { guild_id } = req.params;
+
+		await Guild.update(
+			{ id: guild_id },
+			{
+				widget_enabled: body.enabled,
+				widget_channel_id: body.channel_id,
+			},
+		);
+		// Widget invite for the widget_channel_id gets created as part of the /guilds/{guild.id}/widget.json request
+
+		return res.json(body);
+	},
+);
 
 export default router;