refactor(bot)!: setup desired properties for all transformers (#4435)

* refactor(bot)!: setup desired properties for all transformers

SetupDesiredProps when is given an object that does not corrispond to a transformer object that supports desired properties will behave like TransformProperty on the entire object as when it tries to get the properties for said object it will find `never` as the props and for `IsKeyDesired` a props of `never` means that all props are desired.

* Use Equals helper, clean up a bit the code

* Explicit the IsKeyDesired TProps never behavior

* Add all trasformer objects to bot.transformers.$inferredTypes
This commit is contained in:
Fleny
2026-01-28 05:43:35 +01:00
committed by GitHub
parent bd01ded6bf
commit cf02481086
9 changed files with 321 additions and 323 deletions

View File

@@ -4,17 +4,11 @@ import type { CreateRestManagerOptions, RestManager } from '@discordeno/rest';
import { createRestManager } from '@discordeno/rest';
import type { BigString, GatewayDispatchEventNames, GatewayIntents, RecursivePartial } from '@discordeno/types';
import { createLogger, getBotIdFromToken, type logger } from '@discordeno/utils';
import type {
CompleteDesiredProperties,
DesiredPropertiesBehavior,
SetupDesiredProps,
TransformersDesiredProperties,
TransformersObjects,
} from './desiredProperties.js';
import type { CompleteDesiredProperties, DesiredPropertiesBehavior, TransformersDesiredProperties } from './desiredProperties.js';
import type { EventHandlers } from './events.js';
import { type BotGatewayHandler, createBotGatewayHandlers, type GatewayHandlers } from './handlers.js';
import { type BotHelpers, createBotHelpers } from './helpers.js';
import { createTransformers, type Transformers } from './transformers.js';
import { createTransformers, type TransformerFunctions, type Transformers } from './transformers.js';
/**
* Create a bot object that will maintain the rest and gateway connection.
@@ -166,7 +160,7 @@ export interface Bot<
/** The functions that should transform discord objects to discordeno shaped objects. */
transformers: Transformers<TProps, TBehavior> & {
$inferredTypes: {
[K in keyof TransformersObjects]: SetupDesiredProps<TransformersObjects[K], TProps, TBehavior>;
[K in keyof TransformerFunctions<TProps, TBehavior>]: ReturnType<TransformerFunctions<TProps, TBehavior>[K]>;
};
};
/** The handler functions that should handle incoming discord payloads from gateway and call an event. */

View File

@@ -119,120 +119,128 @@ export interface TransformersObjects {
webhook: Webhook;
}
// NOTE: the top-level objects need both the dependencies and alwaysPresents even if empty when the key is specified, this is due the extends & nullability on DesiredPropertiesMetadata
// internal properties needs to be in the alwaysPresents array, depending on an always present value is accepted
/**
* Metadata for typescript to create the correct types for desired properties
*
* @private This is subject to breaking changes without notices
*/
export const transformersDesiredPropertiesMetadata = {
channel: {
dependencies: {
archived: ['toggles'],
invitable: ['toggles'],
locked: ['toggles'],
nsfw: ['toggles'],
newlyCreated: ['toggles'],
managed: ['toggles'],
},
alwaysPresents: ['toggles', 'internalOverwrites', 'internalThreadMetadata'],
},
guild: {
dependencies: {
threads: ['channels'],
features: ['toggles'],
},
alwaysPresents: [],
},
interaction: {
dependencies: {
respond: ['type', 'token', 'id'],
sendFollowupMessage: ['token'],
edit: ['type', 'token', 'id'],
deferEdit: ['type', 'token', 'id'],
defer: ['type', 'token', 'id'],
delete: ['type', 'token'],
},
alwaysPresents: ['bot', 'acknowledged'],
},
member: {
dependencies: {
deaf: ['toggles'],
mute: ['toggles'],
pending: ['toggles'],
flags: ['toggles'],
didRejoin: ['toggles'],
startedOnboarding: ['toggles'],
bypassesVerification: ['toggles'],
completedOnboarding: ['toggles'],
},
alwaysPresents: [],
},
message: {
dependencies: {
crossposted: ['flags'],
ephemeral: ['flags'],
failedToMentionSomeRolesInThread: ['flags'],
hasThread: ['flags'],
isCrosspost: ['flags'],
loading: ['flags'],
mentionedUserIds: ['mentions'],
mentionEveryone: ['bitfield'],
pinned: ['bitfield'],
sourceMessageDeleted: ['flags'],
suppressEmbeds: ['flags'],
suppressNotifications: ['flags'],
timestamp: ['id'],
tts: ['bitfield'],
urgent: ['flags'],
},
alwaysPresents: ['bitfield', 'flags'],
},
role: {
dependencies: {
hoist: ['toggles'],
managed: ['toggles'],
mentionable: ['toggles'],
premiumSubscriber: ['toggles'],
availableForPurchase: ['toggles'],
guildConnections: ['toggles'],
},
alwaysPresents: ['internalTags'],
},
user: {
dependencies: {
tag: ['username', 'discriminator'],
bot: ['toggles'],
system: ['toggles'],
mfaEnabled: ['toggles'],
verified: ['toggles'],
avatarUrl: ['avatar', 'id'],
displayName: ['username', 'globalName'],
defaultAvatarUrl: ['id', 'discriminator'],
displayAvatarUrl: ['avatar', 'id', 'discriminator'],
createdTimestamp: ['id'],
},
alwaysPresents: [],
},
emoji: {
dependencies: {
animated: ['toggles'],
available: ['toggles'],
managed: ['toggles'],
requireColons: ['toggles'],
},
alwaysPresents: ['toggles'],
},
} as const satisfies DesiredPropertiesMetadata;
/**
* Metadata for typescript to create the correct types for desired properties
*
* @private This is subject to breaking changes without notices
*/
export interface TransformersDesiredPropertiesMetadata extends DesiredPropertiesMetadata {
channel: {
dependencies: {
archived: ['toggles'];
invitable: ['toggles'];
locked: ['toggles'];
nsfw: ['toggles'];
newlyCreated: ['toggles'];
managed: ['toggles'];
};
alwaysPresents: ['toggles', 'internalOverwrites', 'internalThreadMetadata'];
};
guild: {
dependencies: {
threads: ['channels'];
features: ['toggles'];
};
alwaysPresents: [];
};
interaction: {
dependencies: {
respond: ['type', 'token', 'id'];
sendFollowupMessage: ['token'];
edit: ['type', 'token', 'id'];
deferEdit: ['type', 'token', 'id'];
defer: ['type', 'token', 'id'];
delete: ['type', 'token'];
};
alwaysPresents: ['bot', 'acknowledged'];
};
member: {
dependencies: {
deaf: ['toggles'];
mute: ['toggles'];
pending: ['toggles'];
flags: ['toggles'];
didRejoin: ['toggles'];
startedOnboarding: ['toggles'];
bypassesVerification: ['toggles'];
completedOnboarding: ['toggles'];
};
alwaysPresents: [];
};
message: {
dependencies: {
crossposted: ['flags'];
ephemeral: ['flags'];
failedToMentionSomeRolesInThread: ['flags'];
hasThread: ['flags'];
isCrosspost: ['flags'];
loading: ['flags'];
mentionedUserIds: ['mentions'];
mentionEveryone: ['bitfield'];
pinned: ['bitfield'];
sourceMessageDeleted: ['flags'];
suppressEmbeds: ['flags'];
suppressNotifications: ['flags'];
timestamp: ['id'];
tts: ['bitfield'];
urgent: ['flags'];
};
alwaysPresents: ['bitfield', 'flags'];
};
role: {
dependencies: {
hoist: ['toggles'];
managed: ['toggles'];
mentionable: ['toggles'];
premiumSubscriber: ['toggles'];
availableForPurchase: ['toggles'];
guildConnections: ['toggles'];
};
alwaysPresents: ['internalTags'];
};
user: {
dependencies: {
tag: ['username', 'discriminator'];
bot: ['toggles'];
system: ['toggles'];
mfaEnabled: ['toggles'];
verified: ['toggles'];
avatarUrl: ['avatar', 'id'];
displayName: ['username', 'globalName'];
defaultAvatarUrl: ['id', 'discriminator'];
displayAvatarUrl: ['avatar', 'id', 'discriminator'];
createdTimestamp: ['id'];
};
alwaysPresents: [];
};
emoji: {
dependencies: {
animated: ['toggles'];
available: ['toggles'];
managed: ['toggles'];
requireColons: ['toggles'];
};
alwaysPresents: ['toggles'];
};
}
type TransformersDesiredPropertiesMetadata = CompleteByKeys<
typeof transformersDesiredPropertiesMetadata,
keyof DesiredPropertiesMetadata,
{ dependencies: {}; alwaysPresents: [] }
>;
export function createDesiredPropertiesObject<T extends RecursivePartial<TransformersDesiredProperties>, TDefault extends boolean = false>(
desiredProperties: T,
@@ -864,9 +872,12 @@ export function createDesiredPropertiesObject<T extends RecursivePartial<Transfo
} satisfies TransformersDesiredProperties as CompleteDesiredProperties<T, TDefault>;
}
/** @private This is subject to breaking changes without notices */
export type Equals<T1, T2> = Required<T1> extends Required<T2> ? (Required<T2> extends Required<T1> ? true : false) : false;
/** @private This is subject to breaking changes without notices */
export type KeyByValue<TObj, TValue> = {
[Key in keyof TObj]: TObj[Key] extends TValue ? Key : never;
[Key in keyof TObj]: Equals<TObj[Key], TValue> extends true ? Key : never;
}[keyof TObj];
/** @private This is subject to breaking changes without notices */
@@ -874,6 +885,11 @@ export type Complete<TObj, TDefault> = {
[K in keyof TObj]-?: undefined extends TObj[K] ? TDefault : Exclude<TObj[K], undefined>;
};
/** @private This is subject to breaking changes without notices */
export type CompleteByKeys<TObj, Keys extends string, TDefault> = {
[K in Keys]-?: K extends keyof TObj ? (undefined extends TObj[K] ? TDefault : Exclude<TObj[K], undefined>) : TDefault;
};
/** @private This is subject to breaking changes without notices */
export type JoinTuple<T extends string[], TDelimiter extends string> = T extends readonly [infer F extends string, ...infer R extends string[]]
? R['length'] extends 0
@@ -883,26 +899,21 @@ export type JoinTuple<T extends string[], TDelimiter extends string> = T extends
/** @private This is subject to breaking changes without notices */
export type DesiredPropertiesMetadata = {
[K in keyof TransformersObjects]: {
dependencies?: {
[K in keyof TransformersObjects]?: {
dependencies: {
[Key in keyof TransformersObjects[K]]?: (keyof TransformersObjects[K])[];
};
alwaysPresents?: (keyof TransformersObjects[K])[];
alwaysPresents: (keyof TransformersObjects[K])[];
};
};
/** @private This is subject to breaking changes without notices */
export type DesirableProperties<
T extends TransformersObjects[keyof TransformersObjects],
TKey extends keyof TransformersObjects = KeyByValue<TransformersObjects, T>,
> = Exclude<
export type DesirableProperties<T extends TransformersObjects[keyof TransformersObjects]> = Exclude<
keyof T,
// Exclude the props that depend on something else from the desirable properties
| keyof TransformersDesiredPropertiesMetadata[TKey]['dependencies']
// Check if all the keys are "always presents", if this is the case it means we did not specify any always present key
| (keyof T extends NonNullable<TransformersDesiredPropertiesMetadata[TKey]['alwaysPresents']>[number]
? never
: NonNullable<TransformersDesiredPropertiesMetadata[TKey]['alwaysPresents']>[number])
| keyof TransformersDesiredPropertiesMetadata[KeyByValue<TransformersObjects, T>]['dependencies']
// Exclude the props that are always present
| TransformersDesiredPropertiesMetadata[KeyByValue<TransformersObjects, T>]['alwaysPresents'][number]
>;
/** @private This is subject to breaking changes without notices */
@@ -923,23 +934,25 @@ export type AreDependenciesSatisfied<T, TDependencies extends Record<string, str
};
/** @private This is subject to breaking changes without notices */
export type IsKeyDesired<TKey, TDependencies extends Record<string, string[]> | undefined, TProps> = TKey extends keyof TProps // The key has a desired props?
? // Yes, is it true?
TProps[TKey] extends true
? // Yes, this is a key to include
true
: // No, this is a key to exclude
DesiredPropertiesError<`This property is not set as desired in desiredProperties option in createBot(), so you can't use it. More info here: https://discordeno.js.org/desired-props`>
: // No, it is a props with dependencies?
TKey extends keyof TDependencies
? // Yes, has all of its dependencies satisfied?
AreDependenciesSatisfied<TDependencies[TKey], TDependencies, TProps> extends true[]
export type IsKeyDesired<TKey, TDependencies extends Record<string, string[]> | undefined, TProps> = TProps extends never // If the props are never, all props are allowed
? true
: TKey extends keyof TProps // The key has a desired props?
? // Yes, is it true?
TProps[TKey] extends true
? // Yes, this is a key to include
true
: // No, this is a key to not include
DesiredPropertiesError<`This property depends on the following properties: ${JoinTuple<NonNullable<TDependencies>[TKey], ', '>}. Not all of these props are set as desired in desiredProperties option in createBot(), so you can't use it. More info here: https://discordeno.js.org/desired-props`>
: // No, we include it but it does not have neither props nor dependencies
true;
: // No, this is a key to exclude
DesiredPropertiesError<`This property is not set as desired in desiredProperties option in createBot(), so you can't use it. More info here: https://discordeno.js.org/desired-props`>
: // No, it is a props with dependencies?
TKey extends keyof TDependencies
? // Yes, has all of its dependencies satisfied?
AreDependenciesSatisfied<TDependencies[TKey], TDependencies, TProps> extends true[]
? // Yes, this is a key to include
true
: // No, this is a key to not include
DesiredPropertiesError<`This property depends on the following properties: ${JoinTuple<NonNullable<TDependencies>[TKey], ', '>}. Not all of these props are set as desired in desiredProperties option in createBot(), so you can't use it. More info here: https://discordeno.js.org/desired-props`>
: // No, we include it but it does not have neither props nor dependencies
true;
/** The behavior it should be used when resolving an undesired property */
export enum DesiredPropertiesBehavior {
@@ -997,7 +1010,7 @@ export type TransformProperty<T, TProps extends TransformersDesiredProperties, T
? // Yes, check for nested proprieties
Collection<U, TransformProperty<UObj, TProps, TBehavior>>
: // No, is it a Bot?
T extends Bot
Equals<T, Bot> extends true
? // Yes, return a bot with the correct set of props & behavior
Bot<TProps, TBehavior>
: // No, is it a transformed object?
@@ -1005,25 +1018,28 @@ export type TransformProperty<T, TProps extends TransformersDesiredProperties, T
? // Yes, apply the desired props
SetupDesiredProps<T, TProps, TBehavior>
: // No, is it an interaction resolved data member? | We need to check this here because the type itself has not way of getting the desired props
T extends InteractionResolvedDataMember<TransformersDesiredProperties, DesiredPropertiesBehavior>
Equals<T, InteractionResolvedDataMember<TransformersDesiredProperties, DesiredPropertiesBehavior>> extends true
? // Yes, apply the desired props
InteractionResolvedDataMember<TProps, TBehavior>
: // No, is it an interaction resolved data channel? | We need to check this here because the type itself has not way of getting the desired props
T extends InteractionResolvedDataChannel<TransformersDesiredProperties, DesiredPropertiesBehavior>
Equals<T, InteractionResolvedDataChannel<TransformersDesiredProperties, DesiredPropertiesBehavior>> extends true
? // Yes, apply the desired props
InteractionResolvedDataChannel<TProps, TBehavior>
: // Is it an object?
IsObject<T> extends true
? // Yes, we need to ensure nested inside there aren't transformed objects
? // Yes, we need to ensure we transform the nested properties as well
{ [K in keyof T]: TransformProperty<T[K], TProps, TBehavior> }
: // No, this is a normal value such as string / bigint / number
T;
/**
* Apply desired properties to a transformer object.
* Apply desired properties to an object.
*
* @remarks
* If the object is not a transformed object that supports desired properties this function behaves the same as TransformProperty on the entire object
*/
export type SetupDesiredProps<
T extends TransformersObjects[keyof TransformersObjects],
T,
TProps extends TransformersDesiredProperties,
TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey,
> = {

View File

@@ -27,22 +27,27 @@ import type {
} from './transformers/types.js';
export type EventHandlers<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = {
applicationCommandPermissionsUpdate: (command: GuildApplicationCommandPermissions) => unknown;
guildAuditLogEntryCreate: (log: AuditLogEntry, guildId: bigint) => unknown;
automodRuleCreate: (rule: AutoModerationRule) => unknown;
automodRuleUpdate: (rule: AutoModerationRule) => unknown;
automodRuleDelete: (rule: AutoModerationRule) => unknown;
automodActionExecution: (payload: AutoModerationActionExecution) => unknown;
applicationCommandPermissionsUpdate: (command: SetupDesiredProps<GuildApplicationCommandPermissions, TProps, TBehavior>) => unknown;
guildAuditLogEntryCreate: (log: SetupDesiredProps<AuditLogEntry, TProps, TBehavior>, guildId: bigint) => unknown;
automodRuleCreate: (rule: SetupDesiredProps<AutoModerationRule, TProps, TBehavior>) => unknown;
automodRuleUpdate: (rule: SetupDesiredProps<AutoModerationRule, TProps, TBehavior>) => unknown;
automodRuleDelete: (rule: SetupDesiredProps<AutoModerationRule, TProps, TBehavior>) => unknown;
automodActionExecution: (payload: SetupDesiredProps<AutoModerationActionExecution, TProps, TBehavior>) => unknown;
threadCreate: (thread: SetupDesiredProps<Channel, TProps, TBehavior>) => unknown;
threadDelete: (thread: SetupDesiredProps<Channel, TProps, TBehavior>) => unknown;
threadListSync: (payload: {
guildId: bigint;
channelIds?: bigint[];
threads: SetupDesiredProps<Channel, TProps, TBehavior>[];
members: ThreadMember[];
members: SetupDesiredProps<ThreadMember, TProps, TBehavior>[];
}) => unknown;
threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedTimestamp: number; flags: number }) => unknown;
threadMembersUpdate: (payload: { id: bigint; guildId: bigint; addedMembers?: ThreadMember[]; removedMemberIds?: bigint[] }) => unknown;
threadMembersUpdate: (payload: {
id: bigint;
guildId: bigint;
addedMembers?: SetupDesiredProps<ThreadMember, TProps, TBehavior>[];
removedMemberIds?: bigint[];
}) => unknown;
threadUpdate: (thread: SetupDesiredProps<Channel, TProps, TBehavior>) => unknown;
scheduledEventCreate: (event: SetupDesiredProps<ScheduledEvent, TProps, TBehavior>) => unknown;
scheduledEventUpdate: (event: SetupDesiredProps<ScheduledEvent, TProps, TBehavior>) => unknown;
@@ -64,7 +69,7 @@ export type EventHandlers<TProps extends TransformersDesiredProperties, TBehavio
resumed: (shardId: number) => unknown;
rateLimited: (data: DiscordRateLimited, shardId: number) => unknown;
interactionCreate: (interaction: SetupDesiredProps<Interaction, TProps, TBehavior>) => unknown;
integrationCreate: (integration: Integration) => unknown;
integrationCreate: (integration: SetupDesiredProps<Integration, TProps, TBehavior>) => unknown;
integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown;
integrationUpdate: (payload: { guildId: bigint }) => unknown;
inviteCreate: (invite: SetupDesiredProps<Invite, TProps, TBehavior>) => unknown;
@@ -104,7 +109,7 @@ export type EventHandlers<TProps extends TransformersDesiredProperties, TBehavio
emoji: SetupDesiredProps<Emoji, TProps, TBehavior>;
}) => unknown;
reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown;
presenceUpdate: (presence: PresenceUpdate) => unknown;
presenceUpdate: (presence: SetupDesiredProps<PresenceUpdate, TProps, TBehavior>) => unknown;
voiceChannelEffectSend: (payload: {
channelId: bigint;
guildId: bigint;

View File

@@ -9,7 +9,7 @@ export async function handleThreadMembersUpdate(bot: Bot, data: DiscordGatewayPa
bot.events.threadMembersUpdate({
id: bot.transformers.snowflake(payload.id),
guildId: bot.transformers.snowflake(payload.guild_id),
addedMembers: payload.added_members?.map((member) => bot.transformers.threadMember?.(bot, member, { guildId: payload.guild_id })),
addedMembers: payload.added_members?.map((member) => bot.transformers.threadMember(bot, member, { guildId: payload.guild_id })),
removedMemberIds: payload.removed_member_ids?.map((id) => bot.transformers.snowflake(id)),
});
}

View File

@@ -39,18 +39,15 @@ import type {
DiscordConnection,
DiscordCurrentAuthorization,
DiscordFollowedChannel,
DiscordGetGatewayBot,
DiscordGuildPreview,
DiscordGuildWidgetSettings,
DiscordInvite,
DiscordInviteMetadata,
DiscordListArchivedThreads,
DiscordPrunedCount,
DiscordTargetUsersJobStatus,
DiscordTokenExchange,
DiscordTokenRevocation,
DiscordVanityUrl,
DiscordVoiceRegion,
EditApplication,
EditAutoModerationRuleOptions,
EditBotMemberOptions,
@@ -118,6 +115,7 @@ import type {
Channel,
Emoji,
Entitlement,
GetGatewayBot,
Guild,
GuildApplicationCommandPermissions,
GuildOnboarding,
@@ -142,6 +140,7 @@ import type {
Template,
ThreadMember,
User,
VoiceRegion,
VoiceState,
Webhook,
WelcomeScreen,
@@ -332,8 +331,7 @@ export function createBotHelpers<TProps extends TransformersDesiredProperties, T
return bot.transformers.channel(bot, snakelize(await bot.rest.getChannel(channelId)));
},
getChannelInvites: async (channelId) => {
return await bot.rest.getChannelInvites(channelId);
// return (await bot.rest.getChannelInvites(channelId)).map((res) => bot.transformers.invite(bot, snakelize(res)))
return (await bot.rest.getChannelInvites(channelId)).map((res) => bot.transformers.invite(bot, snakelize(res)));
},
getChannels: async (guildId) => {
return (await bot.rest.getChannels(guildId)).map((res) => bot.transformers.channel(bot, snakelize(res), { guildId }));
@@ -859,7 +857,11 @@ export function createBotHelpers<TProps extends TransformersDesiredProperties, T
}
export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = {
createAutomodRule: (guildId: BigString, options: CreateAutoModerationRuleOptions, reason?: string) => Promise<AutoModerationRule>;
createAutomodRule: (
guildId: BigString,
options: CreateAutoModerationRuleOptions,
reason?: string,
) => Promise<SetupDesiredProps<AutoModerationRule, TProps, TBehavior>>;
createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>>;
createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise<SetupDesiredProps<Emoji, TProps, TBehavior>>;
createApplicationEmoji: (options: CreateApplicationEmoji) => Promise<SetupDesiredProps<Emoji, TProps, TBehavior>>;
@@ -868,18 +870,21 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
options: CreateForumPostWithMessage,
reason?: string,
) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>>;
createGlobalApplicationCommand: (command: CreateApplicationCommand, options?: CreateGlobalApplicationCommandOptions) => Promise<ApplicationCommand>;
createGlobalApplicationCommand: (
command: CreateApplicationCommand,
options?: CreateGlobalApplicationCommandOptions,
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
createGuildApplicationCommand: (
command: CreateApplicationCommand,
guildId: BigString,
options?: CreateGuildApplicationCommandOptions,
) => Promise<ApplicationCommand>;
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
createGuildSticker: (
guildId: BigString,
options: CreateGuildStickerOptions,
reason?: string,
) => Promise<SetupDesiredProps<Sticker, TProps, TBehavior>>;
createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise<Template>;
createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise<SetupDesiredProps<Template, TProps, TBehavior>>;
createInvite: (channelId: BigString, options?: CreateChannelInvite, reason?: string) => Promise<Camelize<DiscordInvite>>;
getGuildRoleMemberCounts: (guildId: BigString) => Promise<Record<string, number>>;
createRole: (guildId: BigString, options: CreateGuildRole, reason?: string) => Promise<SetupDesiredProps<Role, TProps, TBehavior>>;
@@ -895,13 +900,13 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
commandId: BigString,
bearerToken: string,
options: Camelize<DiscordApplicationCommandPermissions>[],
) => Promise<GuildApplicationCommandPermissions>;
) => Promise<SetupDesiredProps<GuildApplicationCommandPermissions, TProps, TBehavior>>;
editAutomodRule: (
guildId: BigString,
ruleId: BigString,
options: Partial<EditAutoModerationRuleOptions>,
reason?: string,
) => Promise<AutoModerationRule>;
) => Promise<SetupDesiredProps<AutoModerationRule, TProps, TBehavior>>;
editBotProfile: (options: {
username?: string;
botAvatarURL?: string | null;
@@ -915,16 +920,27 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
messageId: BigString,
options: InteractionCallbackData,
) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
editGlobalApplicationCommand: (commandId: BigString, options: CreateApplicationCommand) => Promise<ApplicationCommand>;
editGlobalApplicationCommand: (
commandId: BigString,
options: CreateApplicationCommand,
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
editGuild: (guildId: BigString, options: ModifyGuild, reason?: string) => Promise<SetupDesiredProps<Guild, TProps, TBehavior>>;
editGuildApplicationCommand: (commandId: BigString, guildId: BigString, options: CreateApplicationCommand) => Promise<ApplicationCommand>;
editGuildApplicationCommand: (
commandId: BigString,
guildId: BigString,
options: CreateApplicationCommand,
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
editGuildSticker: (
guildId: BigString,
stickerId: BigString,
options: AtLeastOne<EditGuildStickerOptions>,
reason?: string,
) => Promise<SetupDesiredProps<Sticker, TProps, TBehavior>>;
editGuildTemplate: (guildId: BigString, templateCode: string, options: ModifyGuildTemplate) => Promise<Template>;
editGuildTemplate: (
guildId: BigString,
templateCode: string,
options: ModifyGuildTemplate,
) => Promise<SetupDesiredProps<Template, TProps, TBehavior>>;
editMessage: (channelId: BigString, messageId: BigString, options: EditMessage) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
editOriginalInteractionResponse: (token: string, options: InteractionCallbackData) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
editRole: (guildId: BigString, roleId: BigString, options: EditGuildRole, reason?: string) => Promise<SetupDesiredProps<Role, TProps, TBehavior>>;
@@ -948,8 +964,16 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
token: string,
options: Omit<ModifyWebhook, 'channelId'>,
) => Promise<SetupDesiredProps<Webhook, TProps, TBehavior>>;
editWelcomeScreen: (guildId: BigString, options: ModifyGuildWelcomeScreen, reason?: string) => Promise<WelcomeScreen>;
editWidgetSettings: (guildId: BigString, options: Camelize<DiscordGuildWidgetSettings>, reason?: string) => Promise<GuildWidgetSettings>;
editWelcomeScreen: (
guildId: BigString,
options: ModifyGuildWelcomeScreen,
reason?: string,
) => Promise<SetupDesiredProps<WelcomeScreen, TProps, TBehavior>>;
editWidgetSettings: (
guildId: BigString,
options: Camelize<DiscordGuildWidgetSettings>,
reason?: string,
) => Promise<SetupDesiredProps<GuildWidgetSettings, TProps, TBehavior>>;
editUserApplicationRoleConnection: (
bearerToken: string,
applicationId: BigString,
@@ -961,9 +985,11 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
options: ExecuteWebhook,
) => Promise<SetupDesiredProps<Message, TProps, TBehavior> | undefined>;
followAnnouncement: (sourceChannelId: BigString, targetChannelId: BigString) => Promise<Camelize<DiscordFollowedChannel>>;
getActiveThreads: (guildId: BigString) => Promise<{ threads: SetupDesiredProps<Channel, TProps, TBehavior>[]; members: ThreadMember[] }>;
getApplicationInfo: () => Promise<Application>;
editApplicationInfo: (body: EditApplication) => Promise<Application>;
getActiveThreads: (
guildId: BigString,
) => Promise<{ threads: SetupDesiredProps<Channel, TProps, TBehavior>[]; members: SetupDesiredProps<ThreadMember, TProps, TBehavior>[] }>;
getApplicationInfo: () => Promise<SetupDesiredProps<Application, TProps, TBehavior>>;
editApplicationInfo: (body: EditApplication) => Promise<SetupDesiredProps<Application, TProps, TBehavior>>;
getCurrentAuthenticationInfo: (bearerToken: string) => Promise<Camelize<DiscordCurrentAuthorization>>;
exchangeToken: (
clientId: BigString,
@@ -975,19 +1001,19 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
guildId: BigString,
commandId: BigString,
options?: GetApplicationCommandPermissionOptions,
) => Promise<GuildApplicationCommandPermissions>;
) => Promise<SetupDesiredProps<GuildApplicationCommandPermissions, TProps, TBehavior>>;
getApplicationCommandPermissions: (
guildId: BigString,
options?: GetApplicationCommandPermissionOptions,
) => Promise<GuildApplicationCommandPermissions[]>;
) => Promise<SetupDesiredProps<GuildApplicationCommandPermissions, TProps, TBehavior>[]>;
getAuditLog: (guildId: BigString, options?: GetGuildAuditLog) => Promise<Camelize<DiscordAuditLog>>;
getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise<AutoModerationRule>;
getAutomodRules: (guildId: BigString) => Promise<AutoModerationRule[]>;
getAvailableVoiceRegions: () => Promise<Camelize<DiscordVoiceRegion>[]>;
getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise<SetupDesiredProps<AutoModerationRule, TProps, TBehavior>>;
getAutomodRules: (guildId: BigString) => Promise<SetupDesiredProps<AutoModerationRule, TProps, TBehavior>[]>;
getAvailableVoiceRegions: () => Promise<SetupDesiredProps<VoiceRegion, TProps, TBehavior>[]>;
getBan: (guildId: BigString, userId: BigString) => Promise<Camelize<DiscordBan>>;
getBans: (guildId: BigString, options?: GetBans) => Promise<Camelize<DiscordBan>[]>;
getChannel: (channelId: BigString) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>>;
getChannelInvites: (channelId: BigString) => Promise<Camelize<DiscordInviteMetadata>[]>;
getChannelInvites: (channelId: BigString) => Promise<SetupDesiredProps<Invite, TProps, TBehavior>[]>;
getChannels: (guildId: BigString) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>[]>;
getChannelWebhooks: (channelId: BigString) => Promise<SetupDesiredProps<Webhook, TProps, TBehavior>[]>;
getDmChannel: (userId: BigString) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>>;
@@ -997,26 +1023,31 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
getEmojis: (guildId: BigString) => Promise<SetupDesiredProps<Emoji, TProps, TBehavior>[]>;
getApplicationEmojis: () => Promise<{ items: SetupDesiredProps<Emoji, TProps, TBehavior>[] }>;
getFollowupMessage: (token: string, messageId: BigString) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
getGatewayBot: () => Promise<Camelize<DiscordGetGatewayBot>>;
getGlobalApplicationCommand: (commandId: BigString) => Promise<ApplicationCommand>;
getGlobalApplicationCommands: (options?: GetGlobalApplicationCommandsOptions) => Promise<ApplicationCommand[]>;
getGatewayBot: () => Promise<SetupDesiredProps<GetGatewayBot, TProps, TBehavior>>;
getGlobalApplicationCommand: (commandId: BigString) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
getGlobalApplicationCommands: (
options?: GetGlobalApplicationCommandsOptions,
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>[]>;
getGuild: (guildId: BigString, options?: { counts?: boolean }) => Promise<SetupDesiredProps<Guild, TProps, TBehavior>>;
getGuilds: (bearerToken: string, options?: GetUserGuilds) => Promise<Partial<SetupDesiredProps<Guild, TProps, TBehavior>>[]>;
getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise<ApplicationCommand>;
getGuildApplicationCommands: (guildId: BigString, options?: GetGuildApplicationCommandsOptions) => Promise<ApplicationCommand[]>;
getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>>;
getGuildApplicationCommands: (
guildId: BigString,
options?: GetGuildApplicationCommandsOptions,
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>[]>;
getGuildPreview: (guildId: BigString) => Promise<Camelize<DiscordGuildPreview>>;
getGuildSticker: (guildId: BigString, stickerId: BigString) => Promise<SetupDesiredProps<Sticker, TProps, TBehavior>>;
getGuildStickers: (guildId: BigString) => Promise<SetupDesiredProps<Sticker, TProps, TBehavior>[]>;
getGuildTemplate: (templateCode: string) => Promise<Template>;
getGuildTemplates: (guildId: BigString) => Promise<Template[]>;
getGuildTemplate: (templateCode: string) => Promise<SetupDesiredProps<Template, TProps, TBehavior>>;
getGuildTemplates: (guildId: BigString) => Promise<SetupDesiredProps<Template, TProps, TBehavior>[]>;
getGuildWebhooks: (guildId: BigString) => Promise<SetupDesiredProps<Webhook, TProps, TBehavior>[]>;
getIntegrations: (guildId: BigString) => Promise<Integration[]>;
getIntegrations: (guildId: BigString) => Promise<SetupDesiredProps<Integration, TProps, TBehavior>[]>;
getInvite: (inviteCode: string, options?: GetInvite) => Promise<SetupDesiredProps<Invite, TProps, TBehavior>>;
getInvites: (guildId: BigString) => Promise<SetupDesiredProps<Invite, TProps, TBehavior>[]>;
getMessage: (channelId: BigString, messageId: BigString) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise<SetupDesiredProps<Message, TProps, TBehavior>[]>;
getStickerPack: (stickerPackId: BigString) => Promise<StickerPack>;
getStickerPacks: () => Promise<StickerPack[]>;
getStickerPack: (stickerPackId: BigString) => Promise<SetupDesiredProps<StickerPack, TProps, TBehavior>>;
getStickerPacks: () => Promise<SetupDesiredProps<StickerPack, TProps, TBehavior>[]>;
getOriginalInteractionResponse: (token: string) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
getChannelPins: (
channelId: BigString,
@@ -1041,7 +1072,7 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
eventId: BigString,
options?: GetScheduledEventUsers,
) => Promise<Array<{ user: SetupDesiredProps<User, TProps, TBehavior>; member?: SetupDesiredProps<Member, TProps, TBehavior> }>>;
getSessionInfo: () => Promise<Camelize<DiscordGetGatewayBot>>;
getSessionInfo: () => Promise<SetupDesiredProps<GetGatewayBot, TProps, TBehavior>>;
getStageInstance: (channelId: BigString) => Promise<SetupDesiredProps<StageInstance, TProps, TBehavior>>;
getOwnVoiceState: (guildId: BigString) => Promise<SetupDesiredProps<VoiceState, TProps, TBehavior>>;
getUserVoiceState: (guildId: BigString, userId: BigString) => Promise<SetupDesiredProps<VoiceState, TProps, TBehavior>>;
@@ -1051,8 +1082,12 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
userId: BigString,
options?: GetThreadMember,
extra?: ThreadMemberTransformerExtra,
) => Promise<ThreadMember>;
getThreadMembers: (channelId: BigString, options?: ListThreadMembers, extra?: ThreadMemberTransformerExtra) => Promise<ThreadMember[]>;
) => Promise<SetupDesiredProps<ThreadMember, TProps, TBehavior>>;
getThreadMembers: (
channelId: BigString,
options?: ListThreadMembers,
extra?: ThreadMemberTransformerExtra,
) => Promise<SetupDesiredProps<ThreadMember, TProps, TBehavior>[]>;
getReactions: (
channelId: BigString,
messageId: BigString,
@@ -1064,7 +1099,7 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
getUserConnections: (bearerToken: string) => Promise<Camelize<DiscordConnection>[]>;
getUserApplicationRoleConnection: (bearerToken: string, applicationId: BigString) => Promise<Camelize<DiscordApplicationRoleConnection>>;
getVanityUrl: (guildId: BigString) => Promise<Camelize<DiscordVanityUrl>>;
getVoiceRegions: (guildId: BigString) => Promise<Camelize<DiscordVoiceRegion>[]>;
getVoiceRegions: (guildId: BigString) => Promise<SetupDesiredProps<VoiceRegion, TProps, TBehavior>[]>;
getWebhook: (webhookId: BigString) => Promise<SetupDesiredProps<Webhook, TProps, TBehavior>>;
getWebhookMessage: (
webhookId: BigString,
@@ -1073,9 +1108,9 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
options?: GetWebhookMessageOptions,
) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
getWebhookWithToken: (webhookId: BigString, token: string) => Promise<SetupDesiredProps<Webhook, TProps, TBehavior>>;
getWelcomeScreen: (guildId: BigString) => Promise<WelcomeScreen>;
getWidget: (guildId: BigString) => Promise<GuildWidget>;
getWidgetSettings: (guildId: BigString) => Promise<GuildWidgetSettings>;
getWelcomeScreen: (guildId: BigString) => Promise<SetupDesiredProps<WelcomeScreen, TProps, TBehavior>>;
getWidget: (guildId: BigString) => Promise<SetupDesiredProps<GuildWidget, TProps, TBehavior>>;
getWidgetSettings: (guildId: BigString) => Promise<SetupDesiredProps<GuildWidgetSettings, TProps, TBehavior>>;
publishMessage: (channelId: BigString, messageId: BigString) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
sendMessage: (channelId: BigString, options: CreateMessageOptions) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
sendFollowupMessage: (token: string, options: InteractionCallbackData) => Promise<SetupDesiredProps<Message, TProps, TBehavior>>;
@@ -1090,16 +1125,16 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
options: StartThreadWithoutMessage,
reason?: string,
) => Promise<SetupDesiredProps<Channel, TProps, TBehavior>>;
syncGuildTemplate: (guildId: BigString) => Promise<Template>;
syncGuildTemplate: (guildId: BigString) => Promise<SetupDesiredProps<Template, TProps, TBehavior>>;
upsertGlobalApplicationCommands: (
commands: CreateApplicationCommand[],
options?: UpsertGlobalApplicationCommandOptions,
) => Promise<ApplicationCommand[]>;
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>[]>;
upsertGuildApplicationCommands: (
guildId: BigString,
commands: CreateApplicationCommand[],
options?: UpsertGuildApplicationCommandOptions,
) => Promise<ApplicationCommand[]>;
) => Promise<SetupDesiredProps<ApplicationCommand, TProps, TBehavior>[]>;
editBotMember: (guildId: BigString, options: EditBotMemberOptions, reason?: string) => Promise<SetupDesiredProps<Member, TProps, TBehavior>>;
editMember: (
guildId: BigString,

View File

@@ -85,8 +85,6 @@ import {
type DesiredPropertiesBehavior,
type SetupDesiredProps,
type TransformersDesiredProperties,
type TransformersObjects,
type TransformProperty,
} from './desiredProperties.js';
import { transformActivity, transformActivityInstance, transformActivityLocation } from './transformers/activity.js';
import { transformApplication } from './transformers/application.js';
@@ -238,62 +236,34 @@ import { transformWidget } from './transformers/widget.js';
import { transformWidgetSettings } from './transformers/widgetSettings.js';
export type TransformerFunctions<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = {
activity: TransformerFunction<TProps, TBehavior, DiscordActivity, Activity, {}, 'unchanged'>;
activity: TransformerFunction<TProps, TBehavior, DiscordActivity, Activity>;
activityInstance: TransformerFunction<TProps, TBehavior, DiscordActivityInstance, ActivityInstance>;
activityLocation: TransformerFunction<TProps, TBehavior, DiscordActivityLocation, ActivityLocation>;
application: TransformerFunction<TProps, TBehavior, DiscordApplication, Application, { shardId?: number }, 'unchanged'>;
applicationCommand: TransformerFunction<TProps, TBehavior, DiscordApplicationCommand, ApplicationCommand, {}, 'unchanged'>;
applicationCommandOption: TransformerFunction<TProps, TBehavior, DiscordApplicationCommandOption, ApplicationCommandOption, {}, 'unchanged'>;
applicationCommandOptionChoice: TransformerFunction<
TProps,
TBehavior,
DiscordApplicationCommandOptionChoice,
ApplicationCommandOptionChoice,
{},
'unchanged'
>;
applicationCommandPermission: TransformerFunction<
TProps,
TBehavior,
DiscordGuildApplicationCommandPermissions,
GuildApplicationCommandPermissions,
{},
'unchanged'
>;
application: TransformerFunction<TProps, TBehavior, DiscordApplication, Application, { shardId?: number }>;
applicationCommand: TransformerFunction<TProps, TBehavior, DiscordApplicationCommand, ApplicationCommand>;
applicationCommandOption: TransformerFunction<TProps, TBehavior, DiscordApplicationCommandOption, ApplicationCommandOption>;
applicationCommandOptionChoice: TransformerFunction<TProps, TBehavior, DiscordApplicationCommandOptionChoice, ApplicationCommandOptionChoice>;
applicationCommandPermission: TransformerFunction<TProps, TBehavior, DiscordGuildApplicationCommandPermissions, GuildApplicationCommandPermissions>;
attachment: TransformerFunction<TProps, TBehavior, DiscordAttachment, Attachment>;
auditLogEntry: TransformerFunction<TProps, TBehavior, DiscordAuditLogEntry, AuditLogEntry, {}, 'unchanged'>;
automodActionExecution: TransformerFunction<
TProps,
TBehavior,
DiscordAutoModerationActionExecution,
AutoModerationActionExecution,
{},
'unchanged'
>;
automodRule: TransformerFunction<TProps, TBehavior, DiscordAutoModerationRule, AutoModerationRule, {}, 'unchanged'>;
auditLogEntry: TransformerFunction<TProps, TBehavior, DiscordAuditLogEntry, AuditLogEntry>;
automodActionExecution: TransformerFunction<TProps, TBehavior, DiscordAutoModerationActionExecution, AutoModerationActionExecution>;
automodRule: TransformerFunction<TProps, TBehavior, DiscordAutoModerationRule, AutoModerationRule>;
avatarDecorationData: TransformerFunction<TProps, TBehavior, DiscordAvatarDecorationData, AvatarDecorationData>;
channel: TransformerFunction<TProps, TBehavior, DiscordChannel, Channel, { guildId?: BigString }>;
collectibles: TransformerFunction<TProps, TBehavior, DiscordCollectibles, Collectibles>;
component: TransformerFunction<
TProps,
TBehavior,
DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse,
Component,
{},
'unchanged'
>;
component: TransformerFunction<TProps, TBehavior, DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse, Component>;
defaultReactionEmoji: TransformerFunction<TProps, TBehavior, DiscordDefaultReactionEmoji, DefaultReactionEmoji>;
embed: TransformerFunction<TProps, TBehavior, DiscordEmbed, Embed, {}, 'unchanged'>;
embed: TransformerFunction<TProps, TBehavior, DiscordEmbed, Embed>;
emoji: TransformerFunction<TProps, TBehavior, DiscordEmoji, Emoji>;
entitlement: TransformerFunction<TProps, TBehavior, DiscordEntitlement, Entitlement>;
forumTag: TransformerFunction<TProps, TBehavior, DiscordForumTag, ForumTag>;
gatewayBot: TransformerFunction<TProps, TBehavior, DiscordGetGatewayBot, GetGatewayBot, {}, 'unchanged'>;
gatewayBot: TransformerFunction<TProps, TBehavior, DiscordGetGatewayBot, GetGatewayBot>;
guild: TransformerFunction<TProps, TBehavior, DiscordGuild, Guild, { shardId?: number }>;
guildOnboarding: TransformerFunction<TProps, TBehavior, DiscordGuildOnboarding, GuildOnboarding>;
guildOnboardingPrompt: TransformerFunction<TProps, TBehavior, DiscordGuildOnboardingPrompt, GuildOnboardingPrompt>;
guildOnboardingPromptOption: TransformerFunction<TProps, TBehavior, DiscordGuildOnboardingPromptOption, GuildOnboardingPromptOption>;
incidentsData: TransformerFunction<TProps, TBehavior, DiscordIncidentsData, IncidentsData>;
integration: TransformerFunction<TProps, TBehavior, DiscordIntegrationCreateUpdate, Integration, {}, 'unchanged'>;
integration: TransformerFunction<TProps, TBehavior, DiscordIntegrationCreateUpdate, Integration>;
interaction: TransformerFunction<TProps, TBehavior, DiscordInteraction, Interaction, { shardId?: number }>;
interactionCallback: TransformerFunction<TProps, TBehavior, DiscordInteractionCallback, InteractionCallback>;
interactionCallbackResponse: TransformerFunction<
@@ -303,21 +273,20 @@ export type TransformerFunctions<TProps extends TransformersDesiredProperties, T
InteractionCallbackResponse,
{ shardId?: number }
>;
interactionDataOptions: TransformerFunction<TProps, TBehavior, DiscordInteractionDataOption, InteractionDataOption, {}, 'unchanged'>;
interactionDataOptions: TransformerFunction<TProps, TBehavior, DiscordInteractionDataOption, InteractionDataOption>;
interactionDataResolved: TransformerFunction<
TProps,
TBehavior,
DiscordInteractionDataResolved,
InteractionDataResolved,
{ shardId?: number; guildId?: BigString },
'transform'
{ shardId?: number; guildId?: BigString }
>;
interactionResource: TransformerFunction<TProps, TBehavior, DiscordInteractionResource, InteractionResource, { shardId?: number }>;
invite: TransformerFunction<TProps, TBehavior, DiscordInviteCreate | DiscordInviteMetadata, Invite, { shardId?: number }>;
inviteStageInstance: TransformerFunction<TProps, TBehavior, DiscordInviteStageInstance, InviteStageInstance, { guildId?: BigString }>;
lobby: TransformerFunction<TProps, TBehavior, DiscordLobby, Lobby>;
lobbyMember: TransformerFunction<TProps, TBehavior, DiscordLobbyMember, LobbyMember>;
mediaGalleryItem: TransformerFunction<TProps, TBehavior, DiscordMediaGalleryItem, MediaGalleryItem, {}, 'unchanged'>;
mediaGalleryItem: TransformerFunction<TProps, TBehavior, DiscordMediaGalleryItem, MediaGalleryItem>;
member: TransformerFunction<TProps, TBehavior, DiscordMember, Member, { guildId?: BigString; userId?: BigString }>;
message: TransformerFunction<TProps, TBehavior, DiscordMessage, Message, { shardId?: number }>;
messageCall: TransformerFunction<TProps, TBehavior, DiscordMessageCall, MessageCall>;
@@ -327,7 +296,7 @@ export type TransformerFunctions<TProps extends TransformersDesiredProperties, T
nameplate: TransformerFunction<TProps, TBehavior, DiscordNameplate, Nameplate>;
poll: TransformerFunction<TProps, TBehavior, DiscordPoll, Poll>;
pollMedia: TransformerFunction<TProps, TBehavior, DiscordPollMedia, PollMedia>;
presence: TransformerFunction<TProps, TBehavior, DiscordPresenceUpdate, PresenceUpdate, {}, 'unchanged'>;
presence: TransformerFunction<TProps, TBehavior, DiscordPresenceUpdate, PresenceUpdate>;
role: TransformerFunction<TProps, TBehavior, DiscordRole, Role, { guildId?: BigString }>;
roleColors: TransformerFunction<TProps, TBehavior, DiscordRoleColors, RoleColors>;
scheduledEvent: TransformerFunction<TProps, TBehavior, DiscordScheduledEvent, ScheduledEvent>;
@@ -336,21 +305,21 @@ export type TransformerFunctions<TProps extends TransformersDesiredProperties, T
soundboardSound: TransformerFunction<TProps, TBehavior, DiscordSoundboardSound, SoundboardSound>;
stageInstance: TransformerFunction<TProps, TBehavior, DiscordStageInstance, StageInstance>;
sticker: TransformerFunction<TProps, TBehavior, DiscordSticker, Sticker>;
stickerPack: TransformerFunction<TProps, TBehavior, DiscordStickerPack, StickerPack, {}, 'unchanged'>;
stickerPack: TransformerFunction<TProps, TBehavior, DiscordStickerPack, StickerPack>;
subscription: TransformerFunction<TProps, TBehavior, DiscordSubscription, Subscription>;
team: TransformerFunction<TProps, TBehavior, DiscordTeam, Team, {}, 'unchanged'>;
template: TransformerFunction<TProps, TBehavior, DiscordTemplate, Template, {}, 'unchanged'>;
threadMember: TransformerFunction<TProps, TBehavior, DiscordThreadMember, ThreadMember, ThreadMemberTransformerExtra, 'unchanged'>;
threadMemberGuildCreate: TransformerFunction<TProps, TBehavior, DiscordThreadMemberGuildCreate, ThreadMemberGuildCreate, {}, 'unchanged'>;
unfurledMediaItem: TransformerFunction<TProps, TBehavior, DiscordUnfurledMediaItem, UnfurledMediaItem, {}, 'unchanged'>;
team: TransformerFunction<TProps, TBehavior, DiscordTeam, Team>;
template: TransformerFunction<TProps, TBehavior, DiscordTemplate, Template>;
threadMember: TransformerFunction<TProps, TBehavior, DiscordThreadMember, ThreadMember, ThreadMemberTransformerExtra>;
threadMemberGuildCreate: TransformerFunction<TProps, TBehavior, DiscordThreadMemberGuildCreate, ThreadMemberGuildCreate>;
unfurledMediaItem: TransformerFunction<TProps, TBehavior, DiscordUnfurledMediaItem, UnfurledMediaItem>;
user: TransformerFunction<TProps, TBehavior, DiscordUser, User>;
userPrimaryGuild: TransformerFunction<TProps, TBehavior, DiscordUserPrimaryGuild, UserPrimaryGuild>;
voiceRegion: TransformerFunction<TProps, TBehavior, DiscordVoiceRegion, VoiceRegion, {}, 'unchanged'>;
voiceRegion: TransformerFunction<TProps, TBehavior, DiscordVoiceRegion, VoiceRegion>;
voiceState: TransformerFunction<TProps, TBehavior, DiscordVoiceState, VoiceState, { guildId?: BigString }>;
webhook: TransformerFunction<TProps, TBehavior, DiscordWebhook, Webhook>;
welcomeScreen: TransformerFunction<TProps, TBehavior, DiscordWelcomeScreen, WelcomeScreen, {}, 'unchanged'>;
widget: TransformerFunction<TProps, TBehavior, DiscordGuildWidget, GuildWidget, {}, 'unchanged'>;
widgetSettings: TransformerFunction<TProps, TBehavior, DiscordGuildWidgetSettings, GuildWidgetSettings, {}, 'unchanged'>;
welcomeScreen: TransformerFunction<TProps, TBehavior, DiscordWelcomeScreen, WelcomeScreen>;
widget: TransformerFunction<TProps, TBehavior, DiscordGuildWidget, GuildWidget>;
widgetSettings: TransformerFunction<TProps, TBehavior, DiscordGuildWidgetSettings, GuildWidgetSettings>;
};
export type Transformers<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = TransformerFunctions<
@@ -562,20 +531,7 @@ export type TransformerFunction<
TPayload,
TTransformed,
TExtra = {},
// Detecting what kind of transformation is being applied is actually pretty hard, so we just do it manually
TKind extends 'desired-props' | 'transform' | 'unchanged' = 'desired-props',
> = (
bot: Bot<TProps, TBehavior>,
payload: TPayload,
extra?: TExtra,
) => TKind extends 'desired-props'
? TTransformed extends TransformersObjects[keyof TransformersObjects]
? SetupDesiredProps<TTransformed, TProps, TBehavior>
: // As fair as i can tell, no transformer is actually in this case
'ERROR: Invalid transformer kind'
: TKind extends 'transform'
? TransformProperty<TTransformed, TProps, TBehavior>
: TTransformed;
> = (bot: Bot<TProps, TBehavior>, payload: TPayload, extra?: TExtra) => SetupDesiredProps<TTransformed, TProps, TBehavior>;
export type TransformerCustomizerFunction<
TProps extends TransformersDesiredProperties,
@@ -590,18 +546,10 @@ export type TransformerCustomizers<TProps extends TransformersDesiredProperties,
TProps,
TBehavior,
infer TPayload,
infer _TTransformed,
infer TExtra,
infer _TKind
infer TTransformed,
infer TExtra
>
? TransformerCustomizerFunction<
TProps,
TBehavior,
TPayload,
// We use ReturnType instead of inferring the transformed value so we don't need to do the logic on the kind as well
ReturnType<Transformers<TProps, TBehavior>[K]>,
BigStringsToBigints<TExtra>
>
? TransformerCustomizerFunction<TProps, TBehavior, TPayload, SetupDesiredProps<TTransformed, TProps, TBehavior>, BigStringsToBigints<TExtra>>
: 'ERROR: Invalid transformer found';
};

View File

@@ -14,7 +14,7 @@ import {
type DiscordSectionComponent,
type DiscordSelectMenuComponent,
type DiscordSeparatorComponent,
type DiscordStringSelectInteractionResponseFromModal,
type DiscordStringSelectInteractionResponse,
type DiscordTextDisplayComponent,
type DiscordTextDisplayInteractionResponse,
type DiscordTextInputComponent,
@@ -24,10 +24,11 @@ import {
MessageComponentTypes,
} from '@discordeno/types';
import type { Bot } from '../bot.js';
import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js';
import type { Component, MediaGalleryItem, UnfurledMediaItem } from './types.js';
export function transformComponent(bot: Bot, payload: DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse): Component {
let component: Component;
let component: SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
// This switch is exhaustive, so we dont need the default case and TS does not error out for the un-initialized component variable
switch (payload.type) {
@@ -81,7 +82,7 @@ export function transformComponent(bot: Bot, payload: DiscordMessageComponent |
export function transformUnfurledMediaItem(bot: Bot, payload: DiscordUnfurledMediaItem): UnfurledMediaItem {
const props = bot.transformers.desiredProperties.unfurledMediaItem;
const mediaItem = {} as UnfurledMediaItem;
const mediaItem = {} as SetupDesiredProps<UnfurledMediaItem, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.url && payload.url) mediaItem.url = payload.url;
if (props.proxyUrl && payload.proxy_url) mediaItem.proxyUrl = payload.proxy_url;
@@ -95,7 +96,7 @@ export function transformUnfurledMediaItem(bot: Bot, payload: DiscordUnfurledMed
export function transformMediaGalleryItem(bot: Bot, payload: DiscordMediaGalleryItem): MediaGalleryItem {
const props = bot.transformers.desiredProperties.mediaGalleryItem;
const galleryItem = {} as MediaGalleryItem;
const galleryItem = {} as SetupDesiredProps<MediaGalleryItem, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.media && payload.media) galleryItem.media = bot.transformers.unfurledMediaItem(bot, payload.media);
if (props.description && payload.description) galleryItem.description = payload.description;
@@ -104,9 +105,9 @@ export function transformMediaGalleryItem(bot: Bot, payload: DiscordMediaGallery
return bot.transformers.customizers.mediaGalleryItem(bot, payload, galleryItem);
}
function transformActionRow(bot: Bot, payload: DiscordActionRow): Component {
function transformActionRow(bot: Bot, payload: DiscordActionRow) {
const props = bot.transformers.desiredProperties.component;
const actionRow = {} as Component;
const actionRow = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) actionRow.type = payload.type;
if (props.id && payload.id) actionRow.id = payload.id;
@@ -116,9 +117,9 @@ function transformActionRow(bot: Bot, payload: DiscordActionRow): Component {
return actionRow;
}
function transformContainerComponent(bot: Bot, payload: DiscordContainerComponent): Component {
function transformContainerComponent(bot: Bot, payload: DiscordContainerComponent) {
const props = bot.transformers.desiredProperties.component;
const container = {} as Component;
const container = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) container.type = payload.type;
if (props.id && payload.id) container.id = payload.id;
@@ -130,9 +131,9 @@ function transformContainerComponent(bot: Bot, payload: DiscordContainerComponen
return container;
}
function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent): Component {
function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent) {
const props = bot.transformers.desiredProperties.component;
const button = {} as Component;
const button = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) button.type = payload.type;
if (props.id && payload.id) button.id = payload.id;
@@ -147,9 +148,9 @@ function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent): Co
return button;
}
function transformInputTextComponent(bot: Bot, payload: DiscordTextInputComponent | DiscordTextInputInteractionResponse): Component {
function transformInputTextComponent(bot: Bot, payload: DiscordTextInputComponent | DiscordTextInputInteractionResponse) {
const props = bot.transformers.desiredProperties.component;
const input = {} as Component;
const input = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) input.type = payload.type;
if (props.id && payload.id) input.id = payload.id;
@@ -169,9 +170,9 @@ function transformInputTextComponent(bot: Bot, payload: DiscordTextInputComponen
return input;
}
function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuComponent | DiscordStringSelectInteractionResponseFromModal): Component {
function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuComponent | DiscordStringSelectInteractionResponse) {
const props = bot.transformers.desiredProperties.component;
const select = {} as Component;
const select = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) select.type = payload.type;
if (props.id && payload.id) select.id = payload.id;
@@ -210,9 +211,9 @@ function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuCompon
return select;
}
function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent): Component {
function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent) {
const props = bot.transformers.desiredProperties.component;
const section = {} as Component;
const section = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) section.type = payload.type;
if (props.id && payload.id) section.id = payload.id;
@@ -222,9 +223,9 @@ function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent):
return section;
}
function transformThumbnailComponent(bot: Bot, payload: DiscordThumbnailComponent): Component {
function transformThumbnailComponent(bot: Bot, payload: DiscordThumbnailComponent) {
const props = bot.transformers.desiredProperties.component;
const thumbnail = {} as Component;
const thumbnail = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) thumbnail.type = payload.type;
if (props.id && payload.id) thumbnail.id = payload.id;
@@ -235,9 +236,9 @@ function transformThumbnailComponent(bot: Bot, payload: DiscordThumbnailComponen
return thumbnail;
}
function transformMediaGalleryComponent(bot: Bot, payload: DiscordMediaGalleryComponent): Component {
function transformMediaGalleryComponent(bot: Bot, payload: DiscordMediaGalleryComponent) {
const props = bot.transformers.desiredProperties.component;
const mediaGallery = {} as Component;
const mediaGallery = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) mediaGallery.type = payload.type;
if (props.id && payload.id) mediaGallery.id = payload.id;
@@ -246,9 +247,9 @@ function transformMediaGalleryComponent(bot: Bot, payload: DiscordMediaGalleryCo
return mediaGallery;
}
function transformFileComponent(bot: Bot, payload: DiscordFileComponent): Component {
function transformFileComponent(bot: Bot, payload: DiscordFileComponent) {
const props = bot.transformers.desiredProperties.component;
const file = {} as Component;
const file = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) file.type = payload.type;
if (props.id && payload.id) file.id = payload.id;
@@ -260,9 +261,9 @@ function transformFileComponent(bot: Bot, payload: DiscordFileComponent): Compon
return file;
}
function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComponent | DiscordTextDisplayInteractionResponse): Component {
function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComponent | DiscordTextDisplayInteractionResponse) {
const props = bot.transformers.desiredProperties.component;
const textDisplay = {} as Component;
const textDisplay = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) textDisplay.type = payload.type;
if (props.id && payload.id) textDisplay.id = payload.id;
@@ -274,9 +275,9 @@ function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComp
return textDisplay;
}
function transformSeparatorComponent(bot: Bot, payload: DiscordSeparatorComponent): Component {
function transformSeparatorComponent(bot: Bot, payload: DiscordSeparatorComponent) {
const props = bot.transformers.desiredProperties.component;
const separator = {} as Component;
const separator = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) separator.type = payload.type;
if (props.id && payload.id) separator.id = payload.id;
@@ -286,9 +287,9 @@ function transformSeparatorComponent(bot: Bot, payload: DiscordSeparatorComponen
return separator;
}
function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent | DiscordLabelInteractionResponse): Component {
function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent | DiscordLabelInteractionResponse) {
const props = bot.transformers.desiredProperties.component;
const label = {} as Component;
const label = {} as SetupDesiredProps<Component, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (props.type && payload.type) label.type = payload.type;
if (props.id && payload.id) label.id = payload.id;

View File

@@ -1,9 +1,10 @@
import { type DiscordPresenceUpdate, PresenceStatus } from '@discordeno/types';
import type { Bot } from '../bot.js';
import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js';
import type { PresenceUpdate, User } from './types.js';
export function transformPresence(bot: Bot, payload: DiscordPresenceUpdate): PresenceUpdate {
const presence = {} as PresenceUpdate;
const presence = {} as SetupDesiredProps<PresenceUpdate, TransformersDesiredProperties, DesiredPropertiesBehavior>;
if (payload.user) presence.user = bot.transformers.user(bot, payload.user) as User;
if (payload.guild_id) presence.guildId = bot.transformers.snowflake(payload.guild_id);

View File

@@ -24,10 +24,8 @@ export function transformWebhook(bot: Bot, payload: DiscordWebhook): typeof bot.
icon: payload.source_guild.icon ? iconHashToBigInt(payload.source_guild.icon) : undefined,
};
if (props.sourceChannel && payload.source_channel)
webhook.sourceChannel = {
id: bot.transformers.snowflake(payload.source_channel.id!),
name: payload.source_channel.name ?? '',
};
// @ts-expect-error TODO: Partials
webhook.sourceChannel = bot.transformers.channel(bot, payload.source_channel, { guildId: payload.guild_id });
if (props.url && payload.url) webhook.url = payload.url;
return bot.transformers.customizers.webhook(bot, payload, webhook);