feat(*): use enums for consistency and speed (#5843)

Co-authored-by: Antonio Román <kyradiscord@gmail.com>
This commit is contained in:
Shubham Parihar
2021-06-15 17:03:31 +05:30
committed by GitHub
parent 671436cbb8
commit f7eeccba4b
9 changed files with 100 additions and 69 deletions

View File

@@ -13,7 +13,7 @@ const {
ChannelTypes, ChannelTypes,
Events, Events,
VerificationLevels, VerificationLevels,
DefaultMessageNotifications, DefaultMessageNotificationLevels,
ExplicitContentFilterLevels, ExplicitContentFilterLevels,
} = require('../util/Constants'); } = require('../util/Constants');
const DataResolver = require('../util/DataResolver'); const DataResolver = require('../util/DataResolver');
@@ -168,14 +168,14 @@ class GuildManager extends BaseManager {
} = {}, } = {},
) { ) {
icon = await DataResolver.resolveImage(icon); icon = await DataResolver.resolveImage(icon);
if (typeof verificationLevel !== 'undefined' && typeof verificationLevel !== 'number') { if (typeof verificationLevel === 'string') {
verificationLevel = VerificationLevels.indexOf(verificationLevel); verificationLevel = VerificationLevels[verificationLevel];
} }
if (typeof defaultMessageNotifications !== 'undefined' && typeof defaultMessageNotifications !== 'number') { if (typeof defaultMessageNotifications === 'string') {
defaultMessageNotifications = DefaultMessageNotifications.indexOf(defaultMessageNotifications); defaultMessageNotifications = DefaultMessageNotificationLevels[defaultMessageNotifications];
} }
if (typeof explicitContentFilter !== 'undefined' && typeof explicitContentFilter !== 'number') { if (typeof explicitContentFilter === 'string') {
explicitContentFilter = ExplicitContentFilterLevels.indexOf(explicitContentFilter); explicitContentFilter = ExplicitContentFilterLevels[explicitContentFilter];
} }
for (const channel of channels) { for (const channel of channels) {
if (channel.type) channel.type = ChannelTypes[channel.type.toUpperCase()]; if (channel.type) channel.type = ChannelTypes[channel.type.toUpperCase()];

View File

@@ -41,7 +41,7 @@ class ClientPresence extends Presence {
if (!activity.type) activity.type = 0; if (!activity.type) activity.type = 0;
data.activities.push({ data.activities.push({
type: typeof activity.type === 'number' ? activity.type : ActivityTypes.indexOf(activity.type), type: typeof activity.type === 'number' ? activity.type : ActivityTypes[activity.type],
name: activity.name, name: activity.name,
url: activity.url, url: activity.url,
}); });
@@ -50,7 +50,7 @@ class ClientPresence extends Presence {
data.activities.push( data.activities.push(
...this.activities.map(a => ({ ...this.activities.map(a => ({
name: a.name, name: a.name,
type: ActivityTypes.indexOf(a.type), type: ActivityTypes[a.type],
url: a.url ?? undefined, url: a.url ?? undefined,
})), })),
); );

View File

@@ -20,7 +20,7 @@ const VoiceStateManager = require('../managers/VoiceStateManager');
const Collection = require('../util/Collection'); const Collection = require('../util/Collection');
const { const {
ChannelTypes, ChannelTypes,
DefaultMessageNotifications, DefaultMessageNotificationLevels,
PartialTypes, PartialTypes,
VerificationLevels, VerificationLevels,
ExplicitContentFilterLevels, ExplicitContentFilterLevels,
@@ -280,11 +280,10 @@ class Guild extends BaseGuild {
this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp; this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp;
/** /**
* The value set for the guild's default message notifications * The default message notification level of the guild
* @type {DefaultMessageNotifications|number} * @type {DefaultMessageNotificationLevel}
*/ */
this.defaultMessageNotifications = this.defaultMessageNotifications = DefaultMessageNotificationLevels[data.default_message_notifications];
DefaultMessageNotifications[data.default_message_notifications] || data.default_message_notifications;
/** /**
* The value set for the guild's system channel flags * The value set for the guild's system channel flags
@@ -831,7 +830,8 @@ class Guild extends BaseGuild {
* @property {Base64Resolvable} [splash] The invite splash image of the guild * @property {Base64Resolvable} [splash] The invite splash image of the guild
* @property {Base64Resolvable} [discoverySplash] The discovery splash image of the guild * @property {Base64Resolvable} [discoverySplash] The discovery splash image of the guild
* @property {Base64Resolvable} [banner] The banner of the guild * @property {Base64Resolvable} [banner] The banner of the guild
* @property {DefaultMessageNotifications|number} [defaultMessageNotifications] The default message notifications * @property {DefaultMessageNotificationLevel|number} [defaultMessageNotifications] The default message notification
* level of the guild
* @property {SystemChannelFlagsResolvable} [systemChannelFlags] The system channel flags of the guild * @property {SystemChannelFlagsResolvable} [systemChannelFlags] The system channel flags of the guild
* @property {ChannelResolvable} [rulesChannel] The rules channel of the guild * @property {ChannelResolvable} [rulesChannel] The rules channel of the guild
* @property {ChannelResolvable} [publicUpdatesChannel] The community updates channel of the guild * @property {ChannelResolvable} [publicUpdatesChannel] The community updates channel of the guild
@@ -859,8 +859,8 @@ class Guild extends BaseGuild {
if (typeof data.verificationLevel !== 'undefined') { if (typeof data.verificationLevel !== 'undefined') {
_data.verification_level = _data.verification_level =
typeof data.verificationLevel === 'number' typeof data.verificationLevel === 'number'
? Number(data.verificationLevel) ? data.verificationLevel
: VerificationLevels.indexOf(data.verificationLevel); : VerificationLevels[data.verificationLevel];
} }
if (typeof data.afkChannel !== 'undefined') { if (typeof data.afkChannel !== 'undefined') {
_data.afk_channel_id = this.client.channels.resolveID(data.afkChannel); _data.afk_channel_id = this.client.channels.resolveID(data.afkChannel);
@@ -878,13 +878,13 @@ class Guild extends BaseGuild {
_data.explicit_content_filter = _data.explicit_content_filter =
typeof data.explicitContentFilter === 'number' typeof data.explicitContentFilter === 'number'
? data.explicitContentFilter ? data.explicitContentFilter
: ExplicitContentFilterLevels.indexOf(data.explicitContentFilter); : ExplicitContentFilterLevels[data.explicitContentFilter];
} }
if (typeof data.defaultMessageNotifications !== 'undefined') { if (typeof data.defaultMessageNotifications !== 'undefined') {
_data.default_message_notifications = _data.default_message_notifications =
typeof data.defaultMessageNotifications === 'string' typeof data.defaultMessageNotifications === 'number'
? DefaultMessageNotifications.indexOf(data.defaultMessageNotifications) ? data.defaultMessageNotifications
: data.defaultMessageNotifications; : DefaultMessageNotificationLevels[data.defaultMessageNotifications];
} }
if (typeof data.systemChannelFlags !== 'undefined') { if (typeof data.systemChannelFlags !== 'undefined') {
_data.system_channel_flags = SystemChannelFlags.resolve(data.systemChannelFlags); _data.system_channel_flags = SystemChannelFlags.resolve(data.systemChannelFlags);
@@ -921,7 +921,7 @@ class Guild extends BaseGuild {
/* eslint-disable max-len */ /* eslint-disable max-len */
/** /**
* Edits the setting of the default message notifications of the guild. * Edits the setting of the default message notifications of the guild.
* @param {DefaultMessageNotifications|number} defaultMessageNotifications The new setting for the default message notifications * @param {DefaultMessageNotificationLevel|number} defaultMessageNotifications The new default message notification level of the guild
* @param {string} [reason] Reason for changing the setting of the default message notifications * @param {string} [reason] Reason for changing the setting of the default message notifications
* @returns {Promise<Guild>} * @returns {Promise<Guild>}
*/ */

View File

@@ -169,7 +169,7 @@ class Activity {
* The type of the activity status * The type of the activity status
* @type {ActivityType} * @type {ActivityType}
*/ */
this.type = ActivityTypes[data.type] || ActivityTypes[ActivityTypes.indexOf(data.type)]; this.type = typeof data.type === 'number' ? ActivityTypes[data.type] : data.type;
/** /**
* If the activity is being streamed, a link to the stream * If the activity is being streamed, a link to the stream

View File

@@ -31,7 +31,7 @@ class Sticker extends Base {
/** /**
* The format of the sticker * The format of the sticker
* @type {StickerFormatTypes} * @type {StickerFormatType}
*/ */
this.format = StickerFormatTypes[sticker.format_type]; this.format = StickerFormatTypes[sticker.format_type];

View File

@@ -29,7 +29,7 @@ class TeamMember extends Base {
/** /**
* The permissions this Team Member has with regard to the team * The permissions this Team Member has with regard to the team
* @type {MembershipStates} * @type {MembershipState}
*/ */
this.membershipState = MembershipStates[data.membership_state]; this.membershipState = MembershipStates[data.membership_state];

View File

@@ -50,7 +50,7 @@ class Webhook {
/** /**
* The type of the webhook * The type of the webhook
* @type {WebhookTypes} * @type {WebhookType}
*/ */
this.type = WebhookTypes[data.type]; this.type = WebhookTypes[data.type];

View File

@@ -488,17 +488,17 @@ exports.SystemMessageTypes = exports.MessageTypes.filter(
); );
/** /**
* <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info> * <info>Bots cannot set a `CUSTOM` activity type, it is only for custom statuses received from users</info>
* The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types: * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types:
* * PLAYING * * PLAYING
* * STREAMING * * STREAMING
* * LISTENING * * LISTENING
* * WATCHING * * WATCHING
* * CUSTOM_STATUS * * CUSTOM
* * COMPETING * * COMPETING
* @typedef {string} ActivityType * @typedef {string} ActivityType
*/ */
exports.ActivityTypes = ['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS', 'COMPETING']; exports.ActivityTypes = createEnum(['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM', 'COMPETING']);
exports.ChannelTypes = createEnum([ exports.ChannelTypes = createEnum([
'TEXT', 'TEXT',
@@ -559,7 +559,7 @@ exports.Colors = {
* * ALL_MEMBERS * * ALL_MEMBERS
* @typedef {string} ExplicitContentFilterLevel * @typedef {string} ExplicitContentFilterLevel
*/ */
exports.ExplicitContentFilterLevels = ['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL_MEMBERS']; exports.ExplicitContentFilterLevels = createEnum(['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL_MEMBERS']);
/** /**
* The value set for the verification levels for a guild: * The value set for the verification levels for a guild:
@@ -570,7 +570,7 @@ exports.ExplicitContentFilterLevels = ['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL
* * VERY_HIGH * * VERY_HIGH
* @typedef {string} VerificationLevel * @typedef {string} VerificationLevel
*/ */
exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH']; exports.VerificationLevels = createEnum(['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH']);
/** /**
* An error encountered while performing an API request. Here are the potential errors: * An error encountered while performing an API request. Here are the potential errors:
@@ -717,45 +717,35 @@ exports.APIErrors = {
}; };
/** /**
* The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types: * The value set for a guild's default message notifications, e.g. `ALL_MESSAGES`. Here are the available types:
* * ALL * * ALL_MESSAGES
* * MENTIONS * * ONLY_MENTIONS
* @typedef {string} DefaultMessageNotifications * @typedef {string} DefaultMessageNotificationLevel
*/ */
exports.DefaultMessageNotifications = ['ALL', 'MENTIONS']; exports.DefaultMessageNotificationLevels = createEnum(['ALL_MESSAGES', 'ONLY_MENTIONS']);
/** /**
* The value set for a team members's membership state: * The value set for a team members's membership state:
* * INVITED * * INVITED
* * ACCEPTED * * ACCEPTED
* @typedef {string} MembershipStates * @typedef {string} MembershipState
*/ */
exports.MembershipStates = [ exports.MembershipStates = createEnum([null, 'INVITED', 'ACCEPTED']);
// They start at 1
null,
'INVITED',
'ACCEPTED',
];
/** /**
* The value set for a webhook's type: * The value set for a webhook's type:
* * Incoming * * Incoming
* * Channel Follower * * Channel Follower
* @typedef {string} WebhookTypes * @typedef {string} WebhookType
*/ */
exports.WebhookTypes = [ exports.WebhookTypes = createEnum([null, 'Incoming', 'Channel Follower']);
// They start at 1
null,
'Incoming',
'Channel Follower',
];
/** /**
* The value set for a sticker's type: * The value set for a sticker's type:
* * PNG * * PNG
* * APNG * * APNG
* * LOTTIE * * LOTTIE
* @typedef {string} StickerFormatTypes * @typedef {string} StickerFormatType
*/ */
exports.StickerFormatTypes = createEnum([null, 'PNG', 'APNG', 'LOTTIE']); exports.StickerFormatTypes = createEnum([null, 'PNG', 'APNG', 'LOTTIE']);

77
typings/index.d.ts vendored
View File

@@ -1,3 +1,12 @@
declare enum ActivityTypes {
PLAYING = 0,
STREAMING = 1,
LISTENING = 2,
WATCHING = 3,
CUSTOM = 4,
COMPETING = 5,
}
declare enum ChannelType { declare enum ChannelType {
text = 0, text = 0,
dm = 1, dm = 1,
@@ -21,6 +30,17 @@ declare enum ChannelTypes {
STAGE = 13, STAGE = 13,
} }
declare enum DefaultMessageNotificationLevels {
ALL_MESSAGES = 0,
ONLY_MENTIONS = 1,
}
declare enum ExplicitContentFilterLevels {
DISABLED = 0,
MEMBERS_WITHOUT_ROLES = 1,
ALL_MEMBERS = 2,
}
declare enum InteractionResponseTypes { declare enum InteractionResponseTypes {
PONG = 1, PONG = 1,
CHANNEL_MESSAGE_WITH_SOURCE = 4, CHANNEL_MESSAGE_WITH_SOURCE = 4,
@@ -40,6 +60,11 @@ declare enum InviteTargetType {
EMBEDDED_APPLICATION = 2, EMBEDDED_APPLICATION = 2,
} }
declare enum MembershipStates {
INVITED = 1,
ACCEPTED = 2,
}
declare enum MessageButtonStyles { declare enum MessageButtonStyles {
PRIMARY = 1, PRIMARY = 1,
SECONDARY = 2, SECONDARY = 2,
@@ -81,6 +106,19 @@ declare enum StickerFormatTypes {
LOTTIE = 3, LOTTIE = 3,
} }
declare enum VerificationLevels {
NONE = 0,
LOW = 1,
MEDIUM = 2,
HIGH = 3,
VERY_HIGH = 4,
}
declare enum WebhookTypes {
Incoming = 1,
'Channel Follower' = 2,
}
type Awaited<T> = T | Promise<T>; type Awaited<T> = T | Promise<T>;
declare module 'discord.js' { declare module 'discord.js' {
@@ -662,13 +700,13 @@ declare module 'discord.js' {
InviteScopes: InviteScope[]; InviteScopes: InviteScope[];
MessageTypes: MessageType[]; MessageTypes: MessageType[];
SystemMessageTypes: SystemMessageType[]; SystemMessageTypes: SystemMessageType[];
ActivityTypes: ActivityType[]; ActivityTypes: typeof ActivityTypes;
StickerFormatTypes: typeof StickerFormatTypes; StickerFormatTypes: typeof StickerFormatTypes;
OverwriteTypes: typeof OverwriteTypes; OverwriteTypes: typeof OverwriteTypes;
ExplicitContentFilterLevels: ExplicitContentFilterLevel[]; ExplicitContentFilterLevels: typeof ExplicitContentFilterLevels;
DefaultMessageNotifications: DefaultMessageNotifications[]; DefaultMessageNotificationLevels: typeof DefaultMessageNotificationLevels;
VerificationLevels: VerificationLevel[]; VerificationLevels: typeof VerificationLevels;
MembershipStates: 'INVITED' | 'ACCEPTED'; MembershipStates: typeof MembershipStates;
ApplicationCommandOptionTypes: typeof ApplicationCommandOptionTypes; ApplicationCommandOptionTypes: typeof ApplicationCommandOptionTypes;
ApplicationCommandPermissionTypes: typeof ApplicationCommandPermissionTypes; ApplicationCommandPermissionTypes: typeof ApplicationCommandPermissionTypes;
InteractionTypes: typeof InteractionTypes; InteractionTypes: typeof InteractionTypes;
@@ -678,6 +716,7 @@ declare module 'discord.js' {
MFALevels: typeof MFALevels; MFALevels: typeof MFALevels;
NSFWLevels: typeof NSFWLevels; NSFWLevels: typeof NSFWLevels;
PrivacyLevels: typeof PrivacyLevels; PrivacyLevels: typeof PrivacyLevels;
WebhookTypes: typeof WebhookTypes;
}; };
export class DataResolver { export class DataResolver {
@@ -740,7 +779,7 @@ declare module 'discord.js' {
public bans: GuildBanManager; public bans: GuildBanManager;
public channels: GuildChannelManager; public channels: GuildChannelManager;
public commands: GuildApplicationCommandManager; public commands: GuildApplicationCommandManager;
public defaultMessageNotifications: DefaultMessageNotifications | number; public defaultMessageNotifications: DefaultMessageNotificationLevel | number;
public deleted: boolean; public deleted: boolean;
public description: string | null; public description: string | null;
public discoverySplash: string | null; public discoverySplash: string | null;
@@ -805,7 +844,7 @@ declare module 'discord.js' {
public setBanner(banner: Base64Resolvable | null, reason?: string): Promise<Guild>; public setBanner(banner: Base64Resolvable | null, reason?: string): Promise<Guild>;
public setChannelPositions(channelPositions: readonly ChannelPosition[]): Promise<Guild>; public setChannelPositions(channelPositions: readonly ChannelPosition[]): Promise<Guild>;
public setDefaultMessageNotifications( public setDefaultMessageNotifications(
defaultMessageNotifications: DefaultMessageNotifications | number, defaultMessageNotifications: DefaultMessageNotificationLevel | number,
reason?: string, reason?: string,
): Promise<Guild>; ): Promise<Guild>;
public setDiscoverySplash(discoverySplash: Base64Resolvable | null, reason?: string): Promise<Guild>; public setDiscoverySplash(discoverySplash: Base64Resolvable | null, reason?: string): Promise<Guild>;
@@ -1762,7 +1801,7 @@ declare module 'discord.js' {
public team: Team; public team: Team;
public readonly id: Snowflake; public readonly id: Snowflake;
public permissions: string[]; public permissions: string[];
public membershipState: MembershipStates; public membershipState: MembershipState;
public user: User; public user: User;
public toString(): string; public toString(): string;
@@ -1931,7 +1970,7 @@ declare module 'discord.js' {
public sourceGuild: Guild | unknown | null; public sourceGuild: Guild | unknown | null;
public sourceChannel: Channel | unknown | null; public sourceChannel: Channel | unknown | null;
public token: string | null; public token: string | null;
public type: WebhookTypes; public type: WebhookType;
} }
export class WebhookClient extends WebhookMixin(BaseClient) { export class WebhookClient extends WebhookMixin(BaseClient) {
@@ -2437,7 +2476,7 @@ declare module 'discord.js' {
type ActivityPlatform = 'desktop' | 'samsung' | 'xbox'; type ActivityPlatform = 'desktop' | 'samsung' | 'xbox';
type ActivityType = 'PLAYING' | 'STREAMING' | 'LISTENING' | 'WATCHING' | 'CUSTOM_STATUS' | 'COMPETING'; type ActivityType = keyof typeof ActivityTypes;
interface AddGuildMemberOptions { interface AddGuildMemberOptions {
accessToken: string; accessToken: string;
@@ -2852,7 +2891,7 @@ declare module 'discord.js' {
binary: string; binary: string;
} }
type DefaultMessageNotifications = 'ALL' | 'MENTIONS'; type DefaultMessageNotificationLevel = keyof typeof DefaultMessageNotificationLevels;
interface EditGuildTemplateOptions { interface EditGuildTemplateOptions {
name?: string; name?: string;
@@ -2894,7 +2933,7 @@ declare module 'discord.js' {
codeBlockContent?: boolean; codeBlockContent?: boolean;
} }
type ExplicitContentFilterLevel = 'DISABLED' | 'MEMBERS_WITHOUT_ROLES' | 'ALL_MEMBERS'; type ExplicitContentFilterLevel = keyof typeof ExplicitContentFilterLevels;
interface Extendable { interface Extendable {
GuildEmoji: typeof GuildEmoji; GuildEmoji: typeof GuildEmoji;
@@ -3072,7 +3111,7 @@ declare module 'discord.js' {
afkChannelID?: Snowflake | number; afkChannelID?: Snowflake | number;
afkTimeout?: number; afkTimeout?: number;
channels?: PartialChannelData[]; channels?: PartialChannelData[];
defaultMessageNotifications?: DefaultMessageNotifications | number; defaultMessageNotifications?: DefaultMessageNotificationLevel | number;
explicitContentFilter?: ExplicitContentFilterLevel | number; explicitContentFilter?: ExplicitContentFilterLevel | number;
icon?: BufferResolvable | Base64Resolvable | null; icon?: BufferResolvable | Base64Resolvable | null;
roles?: PartialRoleData[]; roles?: PartialRoleData[];
@@ -3090,7 +3129,7 @@ declare module 'discord.js' {
name?: string; name?: string;
verificationLevel?: VerificationLevel | number; verificationLevel?: VerificationLevel | number;
explicitContentFilter?: ExplicitContentFilterLevel | number; explicitContentFilter?: ExplicitContentFilterLevel | number;
defaultMessageNotifications?: DefaultMessageNotifications | number; defaultMessageNotifications?: DefaultMessageNotificationLevel | number;
afkChannel?: ChannelResolvable; afkChannel?: ChannelResolvable;
systemChannel?: ChannelResolvable; systemChannel?: ChannelResolvable;
systemChannelFlags?: SystemChannelFlagsResolvable; systemChannelFlags?: SystemChannelFlagsResolvable;
@@ -3281,7 +3320,7 @@ declare module 'discord.js' {
stack: string; stack: string;
} }
type MembershipStates = 'INVITED' | 'ACCEPTED'; type MembershipState = keyof typeof MembershipStates;
type MessageActionRowComponent = MessageButton; type MessageActionRowComponent = MessageButton;
@@ -3805,7 +3844,7 @@ declare module 'discord.js' {
public readonly createdTimestamp: number; public readonly createdTimestamp: number;
public readonly createdAt: Date; public readonly createdAt: Date;
public description: string; public description: string;
public format: StickerFormatTypes; public format: StickerFormatType;
public id: Snowflake; public id: Snowflake;
public name: string; public name: string;
public packID: Snowflake; public packID: Snowflake;
@@ -3813,6 +3852,8 @@ declare module 'discord.js' {
public readonly url: string; public readonly url: string;
} }
type StickerFormatType = keyof typeof StickerFormatTypes;
type SystemChannelFlagsString = type SystemChannelFlagsString =
| 'SUPPRESS_JOIN_NOTIFICATIONS' | 'SUPPRESS_JOIN_NOTIFICATIONS'
| 'SUPPRESS_PREMIUM_SUBSCRIPTIONS' | 'SUPPRESS_PREMIUM_SUBSCRIPTIONS'
@@ -3857,7 +3898,7 @@ declare module 'discord.js' {
uses: number | null; uses: number | null;
} }
type VerificationLevel = 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | 'VERY_HIGH'; type VerificationLevel = keyof typeof VerificationLevels;
type WebhookClientOptions = Pick< type WebhookClientOptions = Pick<
ClientOptions, ClientOptions,
@@ -3880,7 +3921,7 @@ declare module 'discord.js' {
avatarURL?: string; avatarURL?: string;
} }
type WebhookTypes = 'Incoming' | 'Channel Follower'; type WebhookType = keyof typeof WebhookTypes;
interface WebSocketOptions { interface WebSocketOptions {
large_threshold?: number; large_threshold?: number;