7dfdef46a5
[vi] cảm giác đau khổ
639 lines
17 KiB
JavaScript
639 lines
17 KiB
JavaScript
'use strict';
|
|
|
|
const { Collection } = require('@discordjs/collection');
|
|
const { GuildScheduledEvent } = require('./GuildScheduledEvent');
|
|
const Integration = require('./Integration');
|
|
const Invite = require('./Invite');
|
|
const { StageInstance } = require('./StageInstance');
|
|
const { Sticker } = require('./Sticker');
|
|
const Webhook = require('./Webhook');
|
|
const { OverwriteTypes, PartialTypes } = require('../util/Constants');
|
|
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
|
const Util = require('../util/Util');
|
|
|
|
/**
|
|
* The target type of an entry. Here are the available types:
|
|
* * GUILD
|
|
* * CHANNEL
|
|
* * USER
|
|
* * ROLE
|
|
* * INVITE
|
|
* * WEBHOOK
|
|
* * EMOJI
|
|
* * MESSAGE
|
|
* * INTEGRATION
|
|
* * STAGE_INSTANCE
|
|
* * STICKER
|
|
* * THREAD
|
|
* * GUILD_SCHEDULED_EVENT
|
|
* @typedef {string} AuditLogTargetType
|
|
*/
|
|
|
|
/**
|
|
* Key mirror of all available audit log targets.
|
|
* @name GuildAuditLogs.Targets
|
|
* @type {Object<string, string>}
|
|
*/
|
|
const Targets = {
|
|
ALL: 'ALL',
|
|
GUILD: 'GUILD',
|
|
GUILD_SCHEDULED_EVENT: 'GUILD_SCHEDULED_EVENT',
|
|
CHANNEL: 'CHANNEL',
|
|
USER: 'USER',
|
|
ROLE: 'ROLE',
|
|
INVITE: 'INVITE',
|
|
WEBHOOK: 'WEBHOOK',
|
|
EMOJI: 'EMOJI',
|
|
MESSAGE: 'MESSAGE',
|
|
INTEGRATION: 'INTEGRATION',
|
|
STAGE_INSTANCE: 'STAGE_INSTANCE',
|
|
STICKER: 'STICKER',
|
|
THREAD: 'THREAD',
|
|
UNKNOWN: 'UNKNOWN',
|
|
};
|
|
|
|
/**
|
|
* The action of an entry. Here are the available actions:
|
|
* * ALL: null
|
|
* * GUILD_UPDATE: 1
|
|
* * CHANNEL_CREATE: 10
|
|
* * CHANNEL_UPDATE: 11
|
|
* * CHANNEL_DELETE: 12
|
|
* * CHANNEL_OVERWRITE_CREATE: 13
|
|
* * CHANNEL_OVERWRITE_UPDATE: 14
|
|
* * CHANNEL_OVERWRITE_DELETE: 15
|
|
* * MEMBER_KICK: 20
|
|
* * MEMBER_PRUNE: 21
|
|
* * MEMBER_BAN_ADD: 22
|
|
* * MEMBER_BAN_REMOVE: 23
|
|
* * MEMBER_UPDATE: 24
|
|
* * MEMBER_ROLE_UPDATE: 25
|
|
* * MEMBER_MOVE: 26
|
|
* * MEMBER_DISCONNECT: 27
|
|
* * BOT_ADD: 28,
|
|
* * ROLE_CREATE: 30
|
|
* * ROLE_UPDATE: 31
|
|
* * ROLE_DELETE: 32
|
|
* * INVITE_CREATE: 40
|
|
* * INVITE_UPDATE: 41
|
|
* * INVITE_DELETE: 42
|
|
* * WEBHOOK_CREATE: 50
|
|
* * WEBHOOK_UPDATE: 51
|
|
* * WEBHOOK_DELETE: 52
|
|
* * EMOJI_CREATE: 60
|
|
* * EMOJI_UPDATE: 61
|
|
* * EMOJI_DELETE: 62
|
|
* * MESSAGE_DELETE: 72
|
|
* * MESSAGE_BULK_DELETE: 73
|
|
* * MESSAGE_PIN: 74
|
|
* * MESSAGE_UNPIN: 75
|
|
* * INTEGRATION_CREATE: 80
|
|
* * INTEGRATION_UPDATE: 81
|
|
* * INTEGRATION_DELETE: 82
|
|
* * STAGE_INSTANCE_CREATE: 83
|
|
* * STAGE_INSTANCE_UPDATE: 84
|
|
* * STAGE_INSTANCE_DELETE: 85
|
|
* * STICKER_CREATE: 90
|
|
* * STICKER_UPDATE: 91
|
|
* * STICKER_DELETE: 92
|
|
* * GUILD_SCHEDULED_EVENT_CREATE: 100
|
|
* * GUILD_SCHEDULED_EVENT_UPDATE: 101
|
|
* * GUILD_SCHEDULED_EVENT_DELETE: 102
|
|
* * THREAD_CREATE: 110
|
|
* * THREAD_UPDATE: 111
|
|
* * THREAD_DELETE: 112
|
|
* @typedef {?(number|string)} AuditLogAction
|
|
* @see {@link https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events}
|
|
*/
|
|
|
|
/**
|
|
* All available actions keyed under their names to their numeric values.
|
|
* @name GuildAuditLogs.Actions
|
|
* @type {Object<string, number>}
|
|
*/
|
|
const Actions = {
|
|
ALL: null,
|
|
GUILD_UPDATE: 1,
|
|
CHANNEL_CREATE: 10,
|
|
CHANNEL_UPDATE: 11,
|
|
CHANNEL_DELETE: 12,
|
|
CHANNEL_OVERWRITE_CREATE: 13,
|
|
CHANNEL_OVERWRITE_UPDATE: 14,
|
|
CHANNEL_OVERWRITE_DELETE: 15,
|
|
MEMBER_KICK: 20,
|
|
MEMBER_PRUNE: 21,
|
|
MEMBER_BAN_ADD: 22,
|
|
MEMBER_BAN_REMOVE: 23,
|
|
MEMBER_UPDATE: 24,
|
|
MEMBER_ROLE_UPDATE: 25,
|
|
MEMBER_MOVE: 26,
|
|
MEMBER_DISCONNECT: 27,
|
|
BOT_ADD: 28,
|
|
ROLE_CREATE: 30,
|
|
ROLE_UPDATE: 31,
|
|
ROLE_DELETE: 32,
|
|
INVITE_CREATE: 40,
|
|
INVITE_UPDATE: 41,
|
|
INVITE_DELETE: 42,
|
|
WEBHOOK_CREATE: 50,
|
|
WEBHOOK_UPDATE: 51,
|
|
WEBHOOK_DELETE: 52,
|
|
EMOJI_CREATE: 60,
|
|
EMOJI_UPDATE: 61,
|
|
EMOJI_DELETE: 62,
|
|
MESSAGE_DELETE: 72,
|
|
MESSAGE_BULK_DELETE: 73,
|
|
MESSAGE_PIN: 74,
|
|
MESSAGE_UNPIN: 75,
|
|
INTEGRATION_CREATE: 80,
|
|
INTEGRATION_UPDATE: 81,
|
|
INTEGRATION_DELETE: 82,
|
|
STAGE_INSTANCE_CREATE: 83,
|
|
STAGE_INSTANCE_UPDATE: 84,
|
|
STAGE_INSTANCE_DELETE: 85,
|
|
STICKER_CREATE: 90,
|
|
STICKER_UPDATE: 91,
|
|
STICKER_DELETE: 92,
|
|
GUILD_SCHEDULED_EVENT_CREATE: 100,
|
|
GUILD_SCHEDULED_EVENT_UPDATE: 101,
|
|
GUILD_SCHEDULED_EVENT_DELETE: 102,
|
|
THREAD_CREATE: 110,
|
|
THREAD_UPDATE: 111,
|
|
THREAD_DELETE: 112,
|
|
};
|
|
|
|
/**
|
|
* Audit logs entries are held in this class.
|
|
*/
|
|
class GuildAuditLogs {
|
|
constructor(guild, data) {
|
|
if (data.users) for (const user of data.users) guild.client.users._add(user);
|
|
if (data.threads) for (const thread of data.threads) guild.client.channels._add(thread, guild);
|
|
/**
|
|
* Cached webhooks
|
|
* @type {Collection<Snowflake, Webhook>}
|
|
* @private
|
|
*/
|
|
this.webhooks = new Collection();
|
|
if (data.webhooks) {
|
|
for (const hook of data.webhooks) {
|
|
this.webhooks.set(hook.id, new Webhook(guild.client, hook));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cached integrations
|
|
* @type {Collection<Snowflake|string, Integration>}
|
|
* @private
|
|
*/
|
|
this.integrations = new Collection();
|
|
if (data.integrations) {
|
|
for (const integration of data.integrations) {
|
|
this.integrations.set(integration.id, new Integration(guild.client, integration, guild));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The entries for this guild's audit logs
|
|
* @type {Collection<Snowflake, GuildAuditLogsEntry>}
|
|
*/
|
|
this.entries = new Collection();
|
|
for (const item of data.audit_log_entries) {
|
|
const entry = new GuildAuditLogsEntry(this, guild, item);
|
|
this.entries.set(entry.id, entry);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles possible promises for entry targets.
|
|
* @returns {Promise<GuildAuditLogs>}
|
|
*/
|
|
static async build(...args) {
|
|
const logs = new GuildAuditLogs(...args);
|
|
await Promise.all(logs.entries.map(e => e.target));
|
|
return logs;
|
|
}
|
|
|
|
/**
|
|
* The target of an entry. It can be one of:
|
|
* * A guild
|
|
* * A channel
|
|
* * A user
|
|
* * A role
|
|
* * An invite
|
|
* * A webhook
|
|
* * An emoji
|
|
* * A message
|
|
* * An integration
|
|
* * A stage instance
|
|
* * A sticker
|
|
* * A guild scheduled event
|
|
* * A thread
|
|
* * An object with an id key if target was deleted
|
|
* * An object where the keys represent either the new value or the old value
|
|
* @typedef {?(Object|Guild|Channel|User|Role|Invite|Webhook|GuildEmoji|Message|Integration|StageInstance|Sticker|
|
|
* GuildScheduledEvent)} AuditLogEntryTarget
|
|
*/
|
|
|
|
/**
|
|
* Finds the target type from the entry action.
|
|
* @param {AuditLogAction} target The action target
|
|
* @returns {AuditLogTargetType}
|
|
*/
|
|
static targetType(target) {
|
|
if (target < 10) return Targets.GUILD;
|
|
if (target < 20) return Targets.CHANNEL;
|
|
if (target < 30) return Targets.USER;
|
|
if (target < 40) return Targets.ROLE;
|
|
if (target < 50) return Targets.INVITE;
|
|
if (target < 60) return Targets.WEBHOOK;
|
|
if (target < 70) return Targets.EMOJI;
|
|
if (target < 80) return Targets.MESSAGE;
|
|
if (target < 83) return Targets.INTEGRATION;
|
|
if (target < 86) return Targets.STAGE_INSTANCE;
|
|
if (target < 100) return Targets.STICKER;
|
|
if (target < 110) return Targets.GUILD_SCHEDULED_EVENT;
|
|
if (target < 120) return Targets.THREAD;
|
|
return Targets.UNKNOWN;
|
|
}
|
|
|
|
/**
|
|
* The action type of an entry, e.g. `CREATE`. Here are the available types:
|
|
* * CREATE
|
|
* * DELETE
|
|
* * UPDATE
|
|
* * ALL
|
|
* @typedef {string} AuditLogActionType
|
|
*/
|
|
|
|
/**
|
|
* Finds the action type from the entry action.
|
|
* @param {AuditLogAction} action The action target
|
|
* @returns {AuditLogActionType}
|
|
*/
|
|
static actionType(action) {
|
|
if (
|
|
[
|
|
Actions.CHANNEL_CREATE,
|
|
Actions.CHANNEL_OVERWRITE_CREATE,
|
|
Actions.MEMBER_BAN_REMOVE,
|
|
Actions.BOT_ADD,
|
|
Actions.ROLE_CREATE,
|
|
Actions.INVITE_CREATE,
|
|
Actions.WEBHOOK_CREATE,
|
|
Actions.EMOJI_CREATE,
|
|
Actions.MESSAGE_PIN,
|
|
Actions.INTEGRATION_CREATE,
|
|
Actions.STAGE_INSTANCE_CREATE,
|
|
Actions.STICKER_CREATE,
|
|
Actions.GUILD_SCHEDULED_EVENT_CREATE,
|
|
Actions.THREAD_CREATE,
|
|
].includes(action)
|
|
) {
|
|
return 'CREATE';
|
|
}
|
|
|
|
if (
|
|
[
|
|
Actions.CHANNEL_DELETE,
|
|
Actions.CHANNEL_OVERWRITE_DELETE,
|
|
Actions.MEMBER_KICK,
|
|
Actions.MEMBER_PRUNE,
|
|
Actions.MEMBER_BAN_ADD,
|
|
Actions.MEMBER_DISCONNECT,
|
|
Actions.ROLE_DELETE,
|
|
Actions.INVITE_DELETE,
|
|
Actions.WEBHOOK_DELETE,
|
|
Actions.EMOJI_DELETE,
|
|
Actions.MESSAGE_DELETE,
|
|
Actions.MESSAGE_BULK_DELETE,
|
|
Actions.MESSAGE_UNPIN,
|
|
Actions.INTEGRATION_DELETE,
|
|
Actions.STAGE_INSTANCE_DELETE,
|
|
Actions.STICKER_DELETE,
|
|
Actions.GUILD_SCHEDULED_EVENT_DELETE,
|
|
Actions.THREAD_DELETE,
|
|
].includes(action)
|
|
) {
|
|
return 'DELETE';
|
|
}
|
|
|
|
if (
|
|
[
|
|
Actions.GUILD_UPDATE,
|
|
Actions.CHANNEL_UPDATE,
|
|
Actions.CHANNEL_OVERWRITE_UPDATE,
|
|
Actions.MEMBER_UPDATE,
|
|
Actions.MEMBER_ROLE_UPDATE,
|
|
Actions.MEMBER_MOVE,
|
|
Actions.ROLE_UPDATE,
|
|
Actions.INVITE_UPDATE,
|
|
Actions.WEBHOOK_UPDATE,
|
|
Actions.EMOJI_UPDATE,
|
|
Actions.INTEGRATION_UPDATE,
|
|
Actions.STAGE_INSTANCE_UPDATE,
|
|
Actions.STICKER_UPDATE,
|
|
Actions.GUILD_SCHEDULED_EVENT_UPDATE,
|
|
Actions.THREAD_UPDATE,
|
|
].includes(action)
|
|
) {
|
|
return 'UPDATE';
|
|
}
|
|
|
|
return 'ALL';
|
|
}
|
|
|
|
toJSON() {
|
|
return Util.flatten(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Audit logs entry.
|
|
*/
|
|
class GuildAuditLogsEntry {
|
|
constructor(logs, guild, data) {
|
|
const targetType = GuildAuditLogs.targetType(data.action_type);
|
|
/**
|
|
* The target type of this entry
|
|
* @type {AuditLogTargetType}
|
|
*/
|
|
this.targetType = targetType;
|
|
|
|
/**
|
|
* The action type of this entry
|
|
* @type {AuditLogActionType}
|
|
*/
|
|
this.actionType = GuildAuditLogs.actionType(data.action_type);
|
|
|
|
/**
|
|
* Specific action type of this entry in its string presentation
|
|
* @type {AuditLogAction}
|
|
*/
|
|
this.action = Object.keys(Actions).find(k => Actions[k] === data.action_type);
|
|
|
|
/**
|
|
* The reason of this entry
|
|
* @type {?string}
|
|
*/
|
|
this.reason = data.reason ?? null;
|
|
|
|
/**
|
|
* The user that executed this entry
|
|
* @type {?User}
|
|
*/
|
|
this.executor = data.user_id
|
|
? guild.client.options.partials.includes(PartialTypes.USER)
|
|
? guild.client.users._add({ id: data.user_id })
|
|
: guild.client.users.cache.get(data.user_id)
|
|
: null;
|
|
|
|
/**
|
|
* An entry in the audit log representing a specific change.
|
|
* @typedef {Object} AuditLogChange
|
|
* @property {string} key The property that was changed, e.g. `nick` for nickname changes
|
|
* @property {*} [old] The old value of the change, e.g. for nicknames, the old nickname
|
|
* @property {*} [new] The new value of the change, e.g. for nicknames, the new nickname
|
|
*/
|
|
|
|
/**
|
|
* Specific property changes
|
|
* @type {?AuditLogChange[]}
|
|
*/
|
|
this.changes = data.changes?.map(c => ({ key: c.key, old: c.old_value, new: c.new_value })) ?? null;
|
|
|
|
/**
|
|
* The entry's id
|
|
* @type {Snowflake}
|
|
*/
|
|
this.id = data.id;
|
|
|
|
/**
|
|
* Any extra data from the entry
|
|
* @type {?(Object|Role|GuildMember)}
|
|
*/
|
|
this.extra = null;
|
|
switch (data.action_type) {
|
|
case Actions.MEMBER_PRUNE:
|
|
this.extra = {
|
|
removed: Number(data.options.members_removed),
|
|
days: Number(data.options.delete_member_days),
|
|
};
|
|
break;
|
|
|
|
case Actions.MEMBER_MOVE:
|
|
case Actions.MESSAGE_DELETE:
|
|
case Actions.MESSAGE_BULK_DELETE:
|
|
this.extra = {
|
|
channel: guild.channels.cache.get(data.options.channel_id) ?? { id: data.options.channel_id },
|
|
count: Number(data.options.count),
|
|
};
|
|
break;
|
|
|
|
case Actions.MESSAGE_PIN:
|
|
case Actions.MESSAGE_UNPIN:
|
|
this.extra = {
|
|
channel: guild.client.channels.cache.get(data.options.channel_id) ?? { id: data.options.channel_id },
|
|
messageId: data.options.message_id,
|
|
};
|
|
break;
|
|
|
|
case Actions.MEMBER_DISCONNECT:
|
|
this.extra = {
|
|
count: Number(data.options.count),
|
|
};
|
|
break;
|
|
|
|
case Actions.CHANNEL_OVERWRITE_CREATE:
|
|
case Actions.CHANNEL_OVERWRITE_UPDATE:
|
|
case Actions.CHANNEL_OVERWRITE_DELETE:
|
|
switch (Number(data.options.type)) {
|
|
case OverwriteTypes.role:
|
|
this.extra = guild.roles.cache.get(data.options.id) ?? {
|
|
id: data.options.id,
|
|
name: data.options.role_name,
|
|
type: OverwriteTypes[OverwriteTypes.role],
|
|
};
|
|
break;
|
|
|
|
case OverwriteTypes.member:
|
|
this.extra = guild.members.cache.get(data.options.id) ?? {
|
|
id: data.options.id,
|
|
type: OverwriteTypes[OverwriteTypes.member],
|
|
};
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case Actions.STAGE_INSTANCE_CREATE:
|
|
case Actions.STAGE_INSTANCE_DELETE:
|
|
case Actions.STAGE_INSTANCE_UPDATE:
|
|
this.extra = {
|
|
channel: guild.client.channels.cache.get(data.options?.channel_id) ?? { id: data.options?.channel_id },
|
|
};
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/**
|
|
* The target of this entry
|
|
* @type {?AuditLogEntryTarget}
|
|
*/
|
|
this.target = null;
|
|
if (targetType === Targets.UNKNOWN) {
|
|
this.target = this.changes.reduce((o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
}, {});
|
|
this.target.id = data.target_id;
|
|
// MEMBER_DISCONNECT and similar types do not provide a target_id.
|
|
} else if (targetType === Targets.USER && data.target_id) {
|
|
this.target = guild.client.options.partials.includes(PartialTypes.USER)
|
|
? guild.client.users._add({ id: data.target_id })
|
|
: guild.client.users.cache.get(data.target_id);
|
|
} else if (targetType === Targets.GUILD) {
|
|
this.target = guild.client.guilds.cache.get(data.target_id);
|
|
} else if (targetType === Targets.WEBHOOK) {
|
|
this.target =
|
|
logs.webhooks.get(data.target_id) ??
|
|
new Webhook(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{
|
|
id: data.target_id,
|
|
guild_id: guild.id,
|
|
},
|
|
),
|
|
);
|
|
} else if (targetType === Targets.INVITE) {
|
|
let change = this.changes.find(c => c.key === 'code');
|
|
change = change.new ?? change.old;
|
|
|
|
this.target =
|
|
guild.invites.cache.get(change) ??
|
|
new Invite(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{ guild },
|
|
),
|
|
);
|
|
} else if (targetType === Targets.MESSAGE) {
|
|
// Discord sends a channel id for the MESSAGE_BULK_DELETE action type.
|
|
this.target =
|
|
data.action_type === Actions.MESSAGE_BULK_DELETE
|
|
? guild.channels.cache.get(data.target_id) ?? { id: data.target_id }
|
|
: guild.client.users.cache.get(data.target_id);
|
|
} else if (targetType === Targets.INTEGRATION) {
|
|
this.target =
|
|
logs.integrations.get(data.target_id) ??
|
|
new Integration(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{ id: data.target_id },
|
|
),
|
|
guild,
|
|
);
|
|
} else if (targetType === Targets.CHANNEL || targetType === Targets.THREAD) {
|
|
this.target =
|
|
guild.channels.cache.get(data.target_id) ??
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{ id: data.target_id },
|
|
);
|
|
} else if (targetType === Targets.STAGE_INSTANCE) {
|
|
this.target =
|
|
guild.stageInstances.cache.get(data.target_id) ??
|
|
new StageInstance(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{
|
|
id: data.target_id,
|
|
channel_id: data.options?.channel_id,
|
|
guild_id: guild.id,
|
|
},
|
|
),
|
|
);
|
|
} else if (targetType === Targets.STICKER) {
|
|
this.target =
|
|
guild.stickers.cache.get(data.target_id) ??
|
|
new Sticker(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{ id: data.target_id },
|
|
),
|
|
);
|
|
} else if (targetType === Targets.GUILD_SCHEDULED_EVENT) {
|
|
this.target =
|
|
guild.scheduledEvents.cache.get(data.target_id) ??
|
|
new GuildScheduledEvent(
|
|
guild.client,
|
|
this.changes.reduce(
|
|
(o, c) => {
|
|
o[c.key] = c.new ?? c.old;
|
|
return o;
|
|
},
|
|
{ id: data.target_id, guild_id: guild.id },
|
|
),
|
|
);
|
|
} else if (data.target_id) {
|
|
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) ?? { id: data.target_id };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The timestamp this entry was created at
|
|
* @type {number}
|
|
* @readonly
|
|
*/
|
|
get createdTimestamp() {
|
|
return SnowflakeUtil.timestampFrom(this.id);
|
|
}
|
|
|
|
/**
|
|
* The time this entry was created at
|
|
* @type {Date}
|
|
* @readonly
|
|
*/
|
|
get createdAt() {
|
|
return new Date(this.createdTimestamp);
|
|
}
|
|
|
|
toJSON() {
|
|
return Util.flatten(this, { createdTimestamp: true });
|
|
}
|
|
}
|
|
|
|
GuildAuditLogs.Actions = Actions;
|
|
GuildAuditLogs.Targets = Targets;
|
|
GuildAuditLogs.Entry = GuildAuditLogsEntry;
|
|
|
|
module.exports = GuildAuditLogs;
|