feat(helpers,types)!: add guild template transformer (#2132)

* feat(helpers,types)!: add guild template transformer
This adds a template transformer. Also this fixes incorrect type definitions regarding templates.

Breaking Change: The previously called `Template` interface which was used for creating templates has been renamed to `CreateTemplate`

* fmt

* forgot to add this

* use data
This commit is contained in:
ITOH
2022-03-25 11:15:17 +01:00
committed by GitHub
parent 4bdd8330d0
commit 2c2ccb252c
8 changed files with 81 additions and 41 deletions

5
bot.ts
View File

@@ -8,11 +8,13 @@ import {
Message,
Role,
ScheduledEvent,
Template,
transformChannel,
transformGuild,
transformMember,
transformMessage,
transformRole,
transformTemplate,
transformUser,
transformVoiceState,
User,
@@ -67,6 +69,7 @@ import {
DiscordInteractionDataOption,
DiscordReady,
DiscordStickerPack,
DiscordTemplate,
} from "./types/discord.ts";
import { Errors, GatewayDispatchEventNames, GatewayIntents } from "./types/shared.ts";
@@ -407,6 +410,7 @@ export interface Transformers {
stageInstance: (bot: Bot, payload: DiscordStageInstance) => StageInstance;
sticker: (bot: Bot, payload: DiscordSticker) => Sticker;
stickerPack: (bot: Bot, payload: DiscordStickerPack) => StickerPack;
template: (bot: Bot, payload: DiscordTemplate) => Template;
}
export function createTransformers(options: Partial<Transformers>) {
@@ -447,6 +451,7 @@ export function createTransformers(options: Partial<Transformers>) {
sticker: options.sticker || transformSticker,
stickerPack: options.stickerPack || transformStickerPack,
gatewayBot: options.gatewayBot || transformGatewayBot,
template: options.template || transformTemplate,
};
}

View File

@@ -1,10 +1,8 @@
import type { Bot } from "../../bot.ts";
import { Guild } from "../../transformers/guild.ts";
import { User } from "../../transformers/member.ts";
import { DiscordTemplate } from "../../types/discord.ts";
/** Creates a template for the guild. Requires the `MANAGE_GUILD` permission. */
export async function createGuildTemplate(bot: Bot, guildId: bigint, data: Template) {
export async function createGuildTemplate(bot: Bot, guildId: bigint, data: CreateTemplate) {
if (data.name.length < 1 || data.name.length > 100) {
throw new Error("The name can only be in between 1-100 characters.");
}
@@ -13,42 +11,17 @@ export async function createGuildTemplate(bot: Bot, guildId: bigint, data: Templ
throw new Error("The description can only be in between 0-120 characters.");
}
return await bot.rest.runMethod<DiscordTemplate>(bot.rest, "post", bot.constants.endpoints.GUILD_TEMPLATES(guildId), {
code: data.code,
name: data.name,
description: data.description,
usage_count: data.usageCount,
creator_id: data.creatorId,
creator: data.creator,
created_at: data.createdAt,
updated_at: data.updatedAt,
source_guild_id: data.sourceGuildId,
serialized_source_guild: data.serializedSourceGuild,
is_dirty: data.isDirty,
});
return await bot.rest.runMethod<DiscordTemplate>(
bot.rest,
"post",
bot.constants.endpoints.GUILD_TEMPLATES(guildId),
data,
);
}
export interface Template {
/** The template code (unique Id) */
code: string;
/** Template name */
export interface CreateTemplate {
/** Name which the template should have */
name: string;
/** The description for the template */
description: string;
/** Number of times this template has been used */
usageCount: number;
/** The Id of the user who created the template */
creatorId: string;
/** The user who created the template */
creator: User;
/** When this template was created */
createdAt: string;
/** When this template was last synced to the source guild */
updatedAt: string;
/** The Id of the guild this template is based on */
sourceGuildId: string;
/** The guild snapshot this template contains */
serializedSourceGuild: Partial<Guild>;
/** Whether the template has unsynced changes */
isDirty: boolean;
/** Description of the template */
description?: string;
}

View File

@@ -10,5 +10,5 @@ export async function getGuildTemplates(bot: Bot, guildId: bigint) {
bot.constants.endpoints.GUILD_TEMPLATES(guildId),
);
return new Collection(templates.map((template) => [template.code, template]));
return new Collection(templates.map((template) => [template.code, bot.transformers.template(bot, template)]));
}

View File

@@ -3,9 +3,11 @@ import { DiscordTemplate } from "../../types/discord.ts";
/** Returns the guild template if it exists */
export async function getTemplate(bot: Bot, templateCode: string) {
return await bot.rest.runMethod<DiscordTemplate>(
const result = await bot.rest.runMethod<DiscordTemplate>(
bot.rest,
"get",
bot.constants.endpoints.GUILD_TEMPLATE(templateCode),
);
return bot.transformers.template(bot, result);
}

View File

@@ -30,3 +30,4 @@ export * from "./voiceState.ts";
export * from "./webhook.ts";
export * from "./welcomeScreen.ts";
export * from "./widget.ts";
export * from "./template.ts";

23
transformers/template.ts Normal file
View File

@@ -0,0 +1,23 @@
import { Bot } from "../bot.ts";
import { DiscordTemplate } from "../types/discord.ts";
import { Optionalize } from "../types/shared.ts";
export function transformTemplate(bot: Bot, payload: DiscordTemplate) {
const template = {
code: payload.code,
name: payload.name,
description: payload.description,
usageCount: payload.usage_count,
creatorId: bot.transformers.snowflake(payload.creator_id),
creator: bot.transformers.user(bot, payload.creator),
createdAt: Date.parse(payload.created_at),
updatedAt: Date.parse(payload.updated_at),
sourceGuildId: bot.transformers.snowflake(payload.source_guild_id),
serializedSourceGuild: payload.serialized_source_guild,
isDirty: payload.is_dirty ?? undefined,
};
return template as Optionalize<typeof template>;
}
export interface Template extends ReturnType<typeof transformTemplate> {}

View File

@@ -21,6 +21,7 @@ import {
MessageTypes,
MfaLevels,
OverwriteTypes,
PickPartial,
PremiumTiers,
PremiumTypes,
ScheduledEventEntityType,
@@ -2000,7 +2001,36 @@ export interface DiscordTemplate {
/** The Id of the guild this template is based on */
source_guild_id: string;
/** The guild snapshot this template contains */
serialized_source_guild: Partial<DiscordGuild>;
serialized_source_guild:
& Omit<
PickPartial<
DiscordGuild,
| "name"
| "description"
| "verification_level"
| "default_message_notifications"
| "explicit_content_filter"
| "preferred_locale"
| "afk_timeout"
| "channels"
| "afk_channel_id"
| "system_channel_id"
| "system_channel_flags"
>,
"roles"
>
& {
roles: (
& Omit<
PickPartial<
DiscordRole,
"name" | "color" | "hoist" | "mentionable" | "permissions" | "icon" | "unicode_emoji"
>,
"id"
>
& { id: number }
)[];
};
/** Whether the template has unsynced changes */
is_dirty: boolean | null;
}

View File

@@ -1335,3 +1335,9 @@ export type Optionalize<T> =
}
>
: T;
export type PickPartial<T, K extends keyof T> =
& {
[P in keyof T]?: T[P] | undefined;
}
& { [P in K]: T[P] };