fix(GuildAuditLogEntry)!: Fix some incorrect types and runtime logic (#10591)

BREAKING CHANGE: It also doesn't have a `options.channel_id`, so I stopped `.extra.channel` from being set to `{ id: undefined }`
BREAKING CHANGE: Fixed both types and runtime logic here, it previously created a broken `AutoModerationRule`
BREAKING CHANGE: Removed `Targets.GuildOnboarding`, it will fallback to `Targets.Unknown` and generate a placeholder `target` from the `changes`

---------

Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>
Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
cobalt
2025-01-26 07:48:57 -06:00
committed by GitHub
parent b7e0fe3689
commit b820daadd4
3 changed files with 49 additions and 32 deletions

View File

@@ -29,11 +29,12 @@ const Targets = {
Thread: 'Thread', Thread: 'Thread',
ApplicationCommand: 'ApplicationCommand', ApplicationCommand: 'ApplicationCommand',
AutoModeration: 'AutoModeration', AutoModeration: 'AutoModeration',
GuildOnboarding: 'GuildOnboarding',
GuildOnboardingPrompt: 'GuildOnboardingPrompt', GuildOnboardingPrompt: 'GuildOnboardingPrompt',
SoundboardSound: 'SoundboardSound',
Unknown: 'Unknown', Unknown: 'Unknown',
}; };
// TODO: Add soundboard sounds when https://github.com/discordjs/discord.js/pull/10590 is merged
/** /**
* The target of a guild audit log entry. It can be one of: * The target of a guild audit log entry. It can be one of:
* * A guild * * A guild
@@ -42,8 +43,7 @@ const Targets = {
* * A role * * A role
* * An invite * * An invite
* * A webhook * * A webhook
* * An emoji * * A guild emoji
* * A message
* * An integration * * An integration
* * A stage instance * * A stage instance
* * A sticker * * A sticker
@@ -54,7 +54,7 @@ const Targets = {
* * A guild onboarding prompt * * A guild onboarding prompt
* * An object with an id key if target was deleted or fake entity * * An object with an id key if target was deleted or fake entity
* * An object where the keys represent either the new value or the old value * * An object where the keys represent either the new value or the old value
* @typedef {?(Object|Guild|BaseChannel|User|Role|Invite|Webhook|GuildEmoji|Message|Integration|StageInstance|Sticker| * @typedef {?(Object|Guild|BaseChannel|User|Role|Invite|Webhook|GuildEmoji|Integration|StageInstance|Sticker|
* GuildScheduledEvent|ApplicationCommand|AutoModerationRule|GuildOnboardingPrompt)} AuditLogEntryTarget * GuildScheduledEvent|ApplicationCommand|AutoModerationRule|GuildOnboardingPrompt)} AuditLogEntryTarget
*/ */
@@ -82,9 +82,10 @@ const Targets = {
* * Sticker * * Sticker
* * Thread * * Thread
* * GuildScheduledEvent * * GuildScheduledEvent
* * ApplicationCommandPermission * * ApplicationCommand
* * GuildOnboarding
* * GuildOnboardingPrompt * * GuildOnboardingPrompt
* * SoundboardSound
* * AutoModeration
* * Unknown * * Unknown
* @typedef {string} AuditLogTargetType * @typedef {string} AuditLogTargetType
*/ */
@@ -198,7 +199,6 @@ class GuildAuditLogsEntry {
case AuditLogEvent.MemberMove: case AuditLogEvent.MemberMove:
case AuditLogEvent.MessageDelete: case AuditLogEvent.MessageDelete:
case AuditLogEvent.MessageBulkDelete:
this.extra = { this.extra = {
channel: guild.channels.cache.get(data.options.channel_id) ?? { id: data.options.channel_id }, channel: guild.channels.cache.get(data.options.channel_id) ?? { id: data.options.channel_id },
count: Number(data.options.count), count: Number(data.options.count),
@@ -213,6 +213,7 @@ class GuildAuditLogsEntry {
}; };
break; break;
case AuditLogEvent.MessageBulkDelete:
case AuditLogEvent.MemberDisconnect: case AuditLogEvent.MemberDisconnect:
this.extra = { this.extra = {
count: Number(data.options.count), count: Number(data.options.count),
@@ -364,10 +365,15 @@ class GuildAuditLogsEntry {
data.action_type === AuditLogEvent.OnboardingPromptCreate data.action_type === AuditLogEvent.OnboardingPromptCreate
? new GuildOnboardingPrompt(guild.client, changesReduce(this.changes, { id: data.target_id }), guild.id) ? new GuildOnboardingPrompt(guild.client, changesReduce(this.changes, { id: data.target_id }), guild.id)
: changesReduce(this.changes, { id: data.target_id }); : changesReduce(this.changes, { id: data.target_id });
} else if (targetType === Targets.GuildOnboarding) { } else if (targetType === Targets.Role) {
this.target = changesReduce(this.changes, { id: data.target_id }); this.target = guild.roles.cache.get(data.target_id) ?? { id: data.target_id };
} else if (targetType === Targets.Emoji) {
this.target = guild.emojis.cache.get(data.target_id) ?? { id: data.target_id };
// TODO: Uncomment after https://github.com/discordjs/discord.js/pull/10590 is merged
// } else if (targetType === Targets.SoundboardSound) {
// this.target = guild.soundboardSounds.cache.get(data.target_id) ?? { id: data.target_id };
} else if (data.target_id) { } else if (data.target_id) {
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) ?? { id: data.target_id }; this.target = { id: data.target_id };
} }
} }
@@ -391,9 +397,10 @@ class GuildAuditLogsEntry {
if (target < 110) return Targets.GuildScheduledEvent; if (target < 110) return Targets.GuildScheduledEvent;
if (target < 120) return Targets.Thread; if (target < 120) return Targets.Thread;
if (target < 130) return Targets.ApplicationCommand; if (target < 130) return Targets.ApplicationCommand;
if (target >= 140 && target < 150) return Targets.AutoModeration; if (target < 140) return Targets.SoundboardSound;
if (target < 143) return Targets.AutoModeration;
if (target < 146) return Targets.User;
if (target >= 163 && target <= 165) return Targets.GuildOnboardingPrompt; if (target >= 163 && target <= 165) return Targets.GuildOnboardingPrompt;
if (target >= 160 && target < 170) return Targets.GuildOnboarding;
return Targets.Unknown; return Targets.Unknown;
} }
@@ -419,10 +426,9 @@ class GuildAuditLogsEntry {
AuditLogEvent.StickerCreate, AuditLogEvent.StickerCreate,
AuditLogEvent.GuildScheduledEventCreate, AuditLogEvent.GuildScheduledEventCreate,
AuditLogEvent.ThreadCreate, AuditLogEvent.ThreadCreate,
AuditLogEvent.SoundboardSoundCreate,
AuditLogEvent.AutoModerationRuleCreate, AuditLogEvent.AutoModerationRuleCreate,
AuditLogEvent.AutoModerationBlockMessage,
AuditLogEvent.OnboardingPromptCreate, AuditLogEvent.OnboardingPromptCreate,
AuditLogEvent.OnboardingCreate,
].includes(action) ].includes(action)
) { ) {
return 'Create'; return 'Create';
@@ -448,6 +454,7 @@ class GuildAuditLogsEntry {
AuditLogEvent.StickerDelete, AuditLogEvent.StickerDelete,
AuditLogEvent.GuildScheduledEventDelete, AuditLogEvent.GuildScheduledEventDelete,
AuditLogEvent.ThreadDelete, AuditLogEvent.ThreadDelete,
AuditLogEvent.SoundboardSoundDelete,
AuditLogEvent.AutoModerationRuleDelete, AuditLogEvent.AutoModerationRuleDelete,
AuditLogEvent.OnboardingPromptDelete, AuditLogEvent.OnboardingPromptDelete,
].includes(action) ].includes(action)
@@ -473,9 +480,12 @@ class GuildAuditLogsEntry {
AuditLogEvent.GuildScheduledEventUpdate, AuditLogEvent.GuildScheduledEventUpdate,
AuditLogEvent.ThreadUpdate, AuditLogEvent.ThreadUpdate,
AuditLogEvent.ApplicationCommandPermissionUpdate, AuditLogEvent.ApplicationCommandPermissionUpdate,
AuditLogEvent.SoundboardSoundUpdate,
AuditLogEvent.AutoModerationRuleUpdate, AuditLogEvent.AutoModerationRuleUpdate,
AuditLogEvent.AutoModerationBlockMessage,
AuditLogEvent.AutoModerationFlagToChannel,
AuditLogEvent.AutoModerationUserCommunicationDisabled,
AuditLogEvent.OnboardingPromptUpdate, AuditLogEvent.OnboardingPromptUpdate,
AuditLogEvent.OnboardingUpdate,
].includes(action) ].includes(action)
) { ) {
return 'Update'; return 'Update';

View File

@@ -1506,14 +1506,14 @@ export class GuildAuditLogsEntry<
public get createdAt(): Date; public get createdAt(): Date;
public get createdTimestamp(): number; public get createdTimestamp(): number;
public executorId: Snowflake | null; public executorId: Snowflake | null;
public executor: User | null; public executor: User | PartialUser | null;
public extra: TAction extends keyof GuildAuditLogsEntryExtraField ? GuildAuditLogsEntryExtraField[TAction] : null; public extra: TAction extends keyof GuildAuditLogsEntryExtraField ? GuildAuditLogsEntryExtraField[TAction] : null;
public id: Snowflake; public id: Snowflake;
public reason: string | null; public reason: string | null;
public targetId: Snowflake | null; public targetId: Snowflake | null;
public target: TTargetType extends keyof GuildAuditLogsEntryTargetField<TAction> public target: TTargetType extends keyof GuildAuditLogsEntryTargetField<TAction>
? GuildAuditLogsEntryTargetField<TAction>[TTargetType] ? GuildAuditLogsEntryTargetField<TAction>[TTargetType]
: Role | GuildEmoji | { id: Snowflake } | null; : { id: Snowflake | undefined; [x: string]: unknown } | null;
public targetType: TTargetType; public targetType: TTargetType;
public static actionType(action: AuditLogEvent): GuildAuditLogsActionType; public static actionType(action: AuditLogEvent): GuildAuditLogsActionType;
public static targetType(target: AuditLogEvent): GuildAuditLogsTargetType; public static targetType(target: AuditLogEvent): GuildAuditLogsTargetType;
@@ -5659,17 +5659,19 @@ interface GuildAuditLogsTypes {
[AuditLogEvent.ThreadUpdate]: ['Thread', 'Update']; [AuditLogEvent.ThreadUpdate]: ['Thread', 'Update'];
[AuditLogEvent.ThreadDelete]: ['Thread', 'Delete']; [AuditLogEvent.ThreadDelete]: ['Thread', 'Delete'];
[AuditLogEvent.ApplicationCommandPermissionUpdate]: ['ApplicationCommand', 'Update']; [AuditLogEvent.ApplicationCommandPermissionUpdate]: ['ApplicationCommand', 'Update'];
[AuditLogEvent.SoundboardSoundCreate]: ['SoundboardSound', 'Create'];
[AuditLogEvent.SoundboardSoundUpdate]: ['SoundboardSound', 'Update'];
[AuditLogEvent.SoundboardSoundDelete]: ['SoundboardSound', 'Delete'];
[AuditLogEvent.AutoModerationRuleCreate]: ['AutoModeration', 'Create']; [AuditLogEvent.AutoModerationRuleCreate]: ['AutoModeration', 'Create'];
[AuditLogEvent.AutoModerationRuleUpdate]: ['AutoModeration', 'Update']; [AuditLogEvent.AutoModerationRuleUpdate]: ['AutoModeration', 'Update'];
[AuditLogEvent.AutoModerationRuleDelete]: ['AutoModeration', 'Delete']; [AuditLogEvent.AutoModerationRuleDelete]: ['AutoModeration', 'Delete'];
[AuditLogEvent.AutoModerationBlockMessage]: ['AutoModeration', 'Create']; [AuditLogEvent.AutoModerationBlockMessage]: ['User', 'Update'];
[AuditLogEvent.AutoModerationFlagToChannel]: ['AutoModeration', 'Create']; [AuditLogEvent.AutoModerationFlagToChannel]: ['User', 'Update'];
[AuditLogEvent.AutoModerationUserCommunicationDisabled]: ['AutoModeration', 'Create']; [AuditLogEvent.AutoModerationUserCommunicationDisabled]: ['User', 'Update'];
[AuditLogEvent.OnboardingPromptCreate]: ['GuildOnboardingPrompt', 'Create']; [AuditLogEvent.OnboardingPromptCreate]: ['GuildOnboardingPrompt', 'Create'];
[AuditLogEvent.OnboardingPromptUpdate]: ['GuildOnboardingPrompt', 'Update']; [AuditLogEvent.OnboardingPromptUpdate]: ['GuildOnboardingPrompt', 'Update'];
[AuditLogEvent.OnboardingPromptDelete]: ['GuildOnboardingPrompt', 'Delete']; [AuditLogEvent.OnboardingPromptDelete]: ['GuildOnboardingPrompt', 'Delete'];
[AuditLogEvent.OnboardingCreate]: ['GuildOnboarding', 'Create']; // Never have a target: CreatorMonetizationRequestCreated, CreatorMonetizationTermsAccepted, OnboardingCreate, OnboardingUpdate, HomeSettingsCreate, HomeSettingsUpdate
[AuditLogEvent.OnboardingUpdate]: ['GuildOnboarding', 'Update'];
} }
export type GuildAuditLogsActionType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][1] | 'All'; export type GuildAuditLogsActionType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][1] | 'All';
@@ -5680,7 +5682,7 @@ export interface GuildAuditLogsEntryExtraField {
[AuditLogEvent.MemberPrune]: { removed: number; days: number }; [AuditLogEvent.MemberPrune]: { removed: number; days: number };
[AuditLogEvent.MemberMove]: { channel: VoiceBasedChannel | { id: Snowflake }; count: number }; [AuditLogEvent.MemberMove]: { channel: VoiceBasedChannel | { id: Snowflake }; count: number };
[AuditLogEvent.MessageDelete]: { channel: GuildTextBasedChannel | { id: Snowflake }; count: number }; [AuditLogEvent.MessageDelete]: { channel: GuildTextBasedChannel | { id: Snowflake }; count: number };
[AuditLogEvent.MessageBulkDelete]: { channel: GuildTextBasedChannel | { id: Snowflake }; count: number }; [AuditLogEvent.MessageBulkDelete]: { count: number };
[AuditLogEvent.MessagePin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake }; [AuditLogEvent.MessagePin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake };
[AuditLogEvent.MessageUnpin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake }; [AuditLogEvent.MessageUnpin]: { channel: GuildTextBasedChannel | { id: Snowflake }; messageId: Snowflake };
[AuditLogEvent.MemberDisconnect]: { count: number }; [AuditLogEvent.MemberDisconnect]: { count: number };
@@ -5721,13 +5723,13 @@ export interface GuildAuditLogsEntryExtraField {
} }
export interface GuildAuditLogsEntryTargetField<TAction extends AuditLogEvent> { export interface GuildAuditLogsEntryTargetField<TAction extends AuditLogEvent> {
User: User | null; User: User | PartialUser | null;
Guild: Guild; Guild: Guild;
Webhook: Webhook<WebhookType.ChannelFollower | WebhookType.Incoming>; Webhook: Webhook<WebhookType.ChannelFollower | WebhookType.Incoming>;
Invite: Invite; Invite: Invite;
Emoji: GuildEmoji; Emoji: GuildEmoji | { id: Snowflake };
Role: Role; Role: Role | { id: Snowflake };
Message: TAction extends AuditLogEvent.MessageBulkDelete ? Guild | { id: Snowflake } : User; Message: TAction extends AuditLogEvent.MessageBulkDelete ? GuildTextBasedChannel | { id: Snowflake } : User | null;
Integration: Integration; Integration: Integration;
Channel: NonThreadGuildBasedChannel | { id: Snowflake; [x: string]: unknown }; Channel: NonThreadGuildBasedChannel | { id: Snowflake; [x: string]: unknown };
Thread: AnyThreadChannel | { id: Snowflake; [x: string]: unknown }; Thread: AnyThreadChannel | { id: Snowflake; [x: string]: unknown };
@@ -5735,8 +5737,10 @@ export interface GuildAuditLogsEntryTargetField<TAction extends AuditLogEvent> {
Sticker: Sticker; Sticker: Sticker;
GuildScheduledEvent: GuildScheduledEvent; GuildScheduledEvent: GuildScheduledEvent;
ApplicationCommand: ApplicationCommand | { id: Snowflake }; ApplicationCommand: ApplicationCommand | { id: Snowflake };
AutoModerationRule: AutoModerationRule; AutoModeration: AutoModerationRule;
GuildOnboardingPrompt: GuildOnboardingPrompt; GuildOnboardingPrompt: GuildOnboardingPrompt | { id: Snowflake; [x: string]: unknown };
// TODO: Update when https://github.com/discordjs/discord.js/pull/10590 is merged
SoundboardSound: { id: Snowflake };
} }
export interface GuildAuditLogsFetchOptions<Event extends GuildAuditLogsResolvable> { export interface GuildAuditLogsFetchOptions<Event extends GuildAuditLogsResolvable> {
@@ -5752,7 +5756,7 @@ export type GuildAuditLogsResolvable = AuditLogEvent | null;
export type GuildAuditLogsTargetType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][0] | 'Unknown'; export type GuildAuditLogsTargetType = GuildAuditLogsTypes[keyof GuildAuditLogsTypes][0] | 'Unknown';
export type GuildAuditLogsTargets = { export type GuildAuditLogsTargets = {
[Key in GuildAuditLogsTargetType]: GuildAuditLogsTargetType; [Key in GuildAuditLogsTargetType]: Key;
}; };
export type GuildBanResolvable = GuildBan | UserResolvable; export type GuildBanResolvable = GuildBan | UserResolvable;

View File

@@ -2258,15 +2258,18 @@ expectType<Promise<{ channel: GuildTextBasedChannel | { id: Snowflake }; count:
guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.extra), guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.extra),
); );
expectType<Promise<User | null | undefined>>( expectType<Promise<User | PartialUser | null | undefined>>(
guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()?.target), guild.fetchAuditLogs({ type: AuditLogEvent.MemberKick }).then(al => al.entries.first()?.target),
); );
expectType<Promise<StageInstance | undefined>>( expectType<Promise<StageInstance | undefined>>(
guild.fetchAuditLogs({ type: AuditLogEvent.StageInstanceCreate }).then(al => al.entries.first()?.target), guild.fetchAuditLogs({ type: AuditLogEvent.StageInstanceCreate }).then(al => al.entries.first()?.target),
); );
expectType<Promise<User | undefined>>( expectType<Promise<User | null | undefined>>(
guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.target), guild.fetchAuditLogs({ type: AuditLogEvent.MessageDelete }).then(al => al.entries.first()?.target),
); );
expectType<Promise<GuildTextBasedChannel | { id: string } | undefined>>(
guild.fetchAuditLogs({ type: AuditLogEvent.MessageBulkDelete }).then(al => al.entries.first()?.target),
);
declare const AuditLogChange: AuditLogChange; declare const AuditLogChange: AuditLogChange;
// @ts-expect-error // @ts-expect-error