diff --git a/src/api/routes/guilds/index.ts b/src/api/routes/guilds/index.ts
index 78ba93a2..663677dc 100644
--- a/src/api/routes/guilds/index.ts
+++ b/src/api/routes/guilds/index.ts
@@ -55,7 +55,7 @@ router.post(
const guild = await Guild.createGuild({
...body,
owner_id: req.user_id,
- template_guild_id: null,
+ source_guild_id: null,
});
const { autoJoin } = Config.get().guild;
diff --git a/src/api/routes/guilds/templates/index.ts b/src/api/routes/guilds/templates/index.ts
index 391f9c8a..6eb6ffbe 100644
--- a/src/api/routes/guilds/templates/index.ts
+++ b/src/api/routes/guilds/templates/index.ts
@@ -17,10 +17,10 @@
*/
import { route } from "@spacebar/api";
-import { Config, DiscordApiErrors, Guild, Member, Template } from "@spacebar/util";
+import { Config, DiscordApiErrors, Guild, Member, Tag, Template } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
-import { GuildTemplateCreateSchema } from "@spacebar/schemas";
+import { ChannelType, GuildTemplateCreateSchema } from "@spacebar/schemas";
const router: Router = Router({ mergeParams: true });
@@ -64,7 +64,7 @@ router.post("/:template_code", route({ requestBody: "GuildTemplateCreateSchema"
// body comes after the template
...body,
owner_id: req.user_id,
- template_guild_id: template.source_guild_id,
+ source_guild_id: template.source_guild_id,
});
await Member.addToGuild(req.user_id, guild.id);
@@ -87,7 +87,28 @@ async function getTemplate(code: string) {
headers: { "Content-Type": "application/json" },
});
- return (await discordTemplateData.json()) as Template;
+ const templateData = (await discordTemplateData.json()) as Template;
+
+ // Role ID is position in new Discord template schema. Do a little converting.
+ templateData.serialized_source_guild.roles.forEach((role) => {
+ role.position = role.id as unknown as number;
+ });
+
+ templateData.serialized_source_guild.channels.forEach((channel) => {
+ if (channel.type === ChannelType.GUILD_FORUM) {
+ channel.available_tags =
+ channel.available_tags?.map((tag) =>
+ Tag.create({
+ name: tag.name,
+ emoji_id: tag.emoji_id,
+ emoji_name: tag.emoji_name,
+ moderated: tag.moderated,
+ }),
+ ) ?? [];
+ }
+ });
+
+ return templateData;
}
if (code.startsWith("external:")) {
diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts
index cea2bfad..e47d078a 100644
--- a/src/util/entities/Channel.ts
+++ b/src/util/entities/Channel.ts
@@ -218,7 +218,10 @@ export class Channel extends BaseClass {
for (const character of InvisibleCharacters) if (channel.name.includes(character)) throw new HTTPError("Channel name cannot include invalid characters", 403);
// Categories skip these checks on discord.com
- if (channel.type !== ChannelType.GUILD_CATEGORY || guild.features.includes("IRC_LIKE_CATEGORY_NAMES")) {
+ if (
+ (channel.type !== ChannelType.GUILD_CATEGORY && channel.type !== ChannelType.GUILD_STAGE_VOICE && channel.type !== ChannelType.GUILD_VOICE) ||
+ guild.features.includes("IRC_LIKE_CATEGORY_NAMES")
+ ) {
if (channel.name.includes(" ")) throw new HTTPError("Channel name cannot include invalid characters", 403);
if (channel.name.match(/--+/g)) throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403);
diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts
index aac3daf0..43d22aaa 100644
--- a/src/util/entities/Guild.ts
+++ b/src/util/entities/Guild.ts
@@ -310,7 +310,7 @@ export class Guild extends BaseClass {
owner_id?: string;
roles?: Partial<Role>[];
channels?: Partial<Channel>[];
- template_guild_id: string | null;
+ source_guild_id: string | null;
}) {
const guild_id = Snowflake.generate();
@@ -372,7 +372,7 @@ export class Guild extends BaseClass {
guild_id,
id:
// role.id === body.template_guild_id indicates that this is the @everyone role
- role.id === body.template_guild_id ? guild_id : Snowflake.generate(),
+ role.id === body.source_guild_id || role.id == "0" ? guild_id : Snowflake.generate(),
})
.save()
.then(resolve);
diff --git a/src/util/entities/Role.ts b/src/util/entities/Role.ts
index 7908f42d..0647d6da 100644
--- a/src/util/entities/Role.ts
+++ b/src/util/entities/Role.ts
@@ -42,7 +42,7 @@ export class Role extends BaseClass {
@Column()
hoist: boolean;
- @Column()
+ @Column({ default: false })
managed: boolean;
@Column()
diff --git a/src/util/migration/postgres/1771271159006-set-role-managed-default.ts b/src/util/migration/postgres/1771271159006-set-role-managed-default.ts
new file mode 100644
index 00000000..fad55f23
--- /dev/null
+++ b/src/util/migration/postgres/1771271159006-set-role-managed-default.ts
@@ -0,0 +1,13 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class SetRoleManagedDefault1771271159006 implements MigrationInterface {
+ name = "SetRoleManagedDefault1771271159006";
+
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`ALTER TABLE "roles" ALTER COLUMN "managed" SET DEFAULT false`);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(`ALTER TABLE "roles" ALTER COLUMN "managed" DROP DEFAULT`);
+ }
+}
|