'use strict'; const { Collection } = require('@discordjs/collection'); const CachedManager = require('./CachedManager'); const { TypeError } = require('../errors'); const MessagePayload = require('../structures/MessagePayload'); const { Sticker } = require('../structures/Sticker'); /** * Manages API methods for Guild Stickers and stores their cache. * @extends {CachedManager} */ class GuildStickerManager extends CachedManager { constructor(guild, iterable) { super(guild.client, Sticker, iterable); /** * The guild this manager belongs to * @type {Guild} */ this.guild = guild; } /** * The cache of Guild Stickers * @type {Collection} * @name GuildStickerManager#cache */ _add(data, cache) { return super._add(data, cache, { extras: [this.guild] }); } /** * Options for creating a guild sticker. * @typedef {Object} GuildStickerCreateOptions * @property {?string} [description] The description for the sticker * @property {string} [reason] Reason for creating the sticker */ /** * Creates a new custom sticker in the guild. * @param {BufferResolvable|Stream|FileOptions|MessageAttachment} file The file for the sticker * @param {string} name The name for the sticker * @param {string} tags The Discord name of a unicode emoji representing the sticker's expression * @param {GuildStickerCreateOptions} [options] Options * @returns {Promise} The created sticker * @example * // Create a new sticker from a URL * guild.stickers.create('https://i.imgur.com/w3duR07.png', 'rip', 'headstone') * .then(sticker => console.log(`Created new sticker with name ${sticker.name}!`)) * .catch(console.error); * @example * // Create a new sticker from a file on your computer * guild.stickers.create('./memes/banana.png', 'banana', 'banana') * .then(sticker => console.log(`Created new sticker with name ${sticker.name}!`)) * .catch(console.error); */ async create(file, name, tags, { description, reason } = {}) { const resolvedFile = await MessagePayload.resolveFile(file); if (!resolvedFile) throw new TypeError('REQ_RESOURCE_TYPE'); file = { ...resolvedFile, key: 'file' }; const data = { name, tags, description: description ?? '' }; const sticker = await this.client.api .guilds(this.guild.id) .stickers.post({ data, files: [file], reason, dontUsePayloadJSON: true }); return this.client.actions.GuildStickerCreate.handle(this.guild, sticker).sticker; } /** * Data that resolves to give a Sticker object. This can be: * * A Sticker object * * A Snowflake * @typedef {Sticker|Snowflake} StickerResolvable */ /** * Resolves a StickerResolvable to a Sticker object. * @method resolve * @memberof GuildStickerManager * @instance * @param {StickerResolvable} sticker The Sticker resolvable to identify * @returns {?Sticker} */ /** * Resolves a StickerResolvable to a Sticker id string. * @method resolveId * @memberof GuildStickerManager * @instance * @param {StickerResolvable} sticker The Sticker resolvable to identify * @returns {?Snowflake} */ /** * Edits a sticker. * @param {StickerResolvable} sticker The sticker to edit * @param {GuildStickerEditData} [data] The new data for the sticker * @param {string} [reason] Reason for editing this sticker * @returns {Promise} */ async edit(sticker, data, reason) { const stickerId = this.resolveId(sticker); if (!stickerId) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable'); const d = await this.client.api.guilds(this.guild.id).stickers(stickerId).patch({ data, reason, }); const existing = this.cache.get(stickerId); if (existing) { const clone = existing._clone(); clone._patch(d); return clone; } return this._add(d); } /** * Deletes a sticker. * @param {StickerResolvable} sticker The sticker to delete * @param {string} [reason] Reason for deleting this sticker * @returns {Promise} */ async delete(sticker, reason) { sticker = this.resolveId(sticker); if (!sticker) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable'); await this.client.api.guilds(this.guild.id).stickers(sticker).delete({ reason }); } /** * Obtains one or more stickers from Discord, or the sticker cache if they're already available. * @param {Snowflake} [id] The Sticker's id * @param {BaseFetchOptions} [options] Additional options for this fetch * @returns {Promise>} * @example * // Fetch all stickers from the guild * message.guild.stickers.fetch() * .then(stickers => console.log(`There are ${stickers.size} stickers.`)) * .catch(console.error); * @example * // Fetch a single sticker * message.guild.stickers.fetch('222078108977594368') * .then(sticker => console.log(`The sticker name is: ${sticker.name}`)) * .catch(console.error); */ async fetch(id, { cache = true, force = false } = {}) { if (id) { if (!force) { const existing = this.cache.get(id); if (existing) return existing; } const sticker = await this.client.api.guilds(this.guild.id).stickers(id).get(); return this._add(sticker, cache); } const data = await this.client.api.guilds(this.guild.id).stickers.get(); return new Collection(data.map(sticker => [sticker.id, this._add(sticker, cache)])); } /** * Fetches the user who uploaded this sticker, if this is a guild sticker. * @param {StickerResolvable} sticker The sticker to fetch the user for * @returns {Promise} */ async fetchUser(sticker) { sticker = this.resolve(sticker); if (!sticker) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable'); const data = await this.client.api.guilds(this.guild.id).stickers(sticker.id).get(); sticker._patch(data); return sticker.user; } } module.exports = GuildStickerManager;