import Client from "../Client.js";
import { CDN_BASE_URL, TO_JSON_TYPES_ENUM } from "../constants.js";
import util from "util";
/**
* Represents an attachment.
* @see {@link https://discord.com/developers/docs/resources/channel#attachment-object-attachment-structure}
*/
class Attachment {
#_client;
#_id;
#_channel_id;
#_urlData;
#name;
#size;
/**
* Creates a structure for an attachment.
* @param {Client} client The client instance.
* @param {Object} data Attachment data from Discord.
* @param {Object} options Additional options for the attachment.
* @param {String} options.channelId The ID of the channel that this attachment belongs to.
*/
constructor(client, data, { channelId } = {}) {
if (!(client instanceof Client))
throw new TypeError("GLUON: Client must be an instance of Client");
if (typeof data !== "object")
throw new TypeError("GLUON: Data must be an object");
if (typeof channelId !== "string")
throw new TypeError("GLUON: Channel ID must be a string");
/**
* The client instance.
* @type {Client}
* @private
*/
this.#_client = client;
/**
* The id of the attachment.
* @type {BigInt}
* @private
*/
this.#_id = BigInt(data.id);
/**
* The name of the file.
* @type {String}
* @private
*/
this.#name = data.filename;
/**
* The size of the file.
* @type {Number}
* @private
*/
this.#size = data.size;
if (data.url) {
/**
* Data about the file url.
* @type {Object?}
* @private
*/
this.#_urlData = {};
const urlParams = new URL(data.url).searchParams;
this.#_urlData.ex = BigInt(`0x${urlParams.get("ex")}`);
this.#_urlData.is = BigInt(`0x${urlParams.get("is")}`);
this.#_urlData.hm = BigInt(`0x${urlParams.get("hm")}`);
}
/**
* The channel that this attachment belongs to.
* @type {BigInt}
* @private
*/
this.#_channel_id = BigInt(channelId);
}
/**
* The id of the attachment.
* @type {String}
* @readonly
* @public
*/
get id() {
return String(this.#_id);
}
/**
* The name of the file.
* @type {String}
* @readonly
* @public
*/
get name() {
return this.#name;
}
/**
* The size of the file.
* @type {Number}
* @readonly
* @public
*/
get size() {
return this.#size;
}
/**
* The url to the file.
* @type {String}
* @readonly
* @public
*/
get url() {
if (!this.#_urlData) return null;
const url = new URL(
`${CDN_BASE_URL}/attachments/${this.channelId}/${this.id}/${this.name}`,
);
url.searchParams.append("ex", this.#_urlData.ex.toString(16));
url.searchParams.append("is", this.#_urlData.is.toString(16));
url.searchParams.append("hm", this.#_urlData.hm.toString(16));
return url.href;
}
/**
* The channel that this attachment belongs to.
* @type {String}
* @readonly
* @public
*/
get channelId() {
return this.#_channel_id ? String(this.#_channel_id) : undefined;
}
/**
* @method
* @public
*/
toString() {
return `<Attachment: ${this.id}>`;
}
/**
* @method
* @public
*/
[util.inspect.custom]() {
return this.toString();
}
/**
* Returns the JSON representation of this structure.
* @param {Number} format The format to return the data in.
* @returns {Object}
* @public
* @method
*/
toJSON(format) {
switch (format) {
case TO_JSON_TYPES_ENUM.STORAGE_FORMAT: {
return {
id: this.id,
filename: this.name,
size: this.size,
};
}
case TO_JSON_TYPES_ENUM.CACHE_FORMAT:
case TO_JSON_TYPES_ENUM.DISCORD_FORMAT:
default: {
return {
id: this.id,
filename: this.name,
size: this.size,
url: this.url,
};
}
}
}
}
export default Attachment;