1- import type { JSONEncodable } from '@discordjs/util' ;
1+ import type { Buffer } from 'node:buffer' ;
2+ import type { JSONEncodable , RawFile } from '@discordjs/util' ;
23import type { RESTAPIAttachment , Snowflake } from 'discord-api-types/v10' ;
34import { validate } from '../util/validation.js' ;
45import { attachmentPredicate } from './Assertions.js' ;
@@ -12,21 +13,33 @@ export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
1213 */
1314 private readonly data : Partial < RESTAPIAttachment > ;
1415
16+ /**
17+ * This data is not included in the output of `toJSON()`. For this class specifically, this refers to binary data
18+ * that will wind up being included in the multipart/form-data request, if used with the `MessageBuilder`.
19+ * To retrieve this data, use {@link getRawFile}.
20+ *
21+ * @remarks This cannot be set via the constructor, primarily because of the behavior described
22+ * {@link https://discord.com/developers/docs/reference#editing-message-attachments | here}.
23+ * That is, when editing a message's attachments, you should only be providing file data for new attachments.
24+ */
25+ private readonly fileData : Partial < Pick < RawFile , 'contentType' | 'data' > > ;
26+
1527 /**
1628 * Creates a new attachment builder.
1729 *
1830 * @param data - The API data to create this attachment with
1931 */
2032 public constructor ( data : Partial < RESTAPIAttachment > = { } ) {
2133 this . data = structuredClone ( data ) ;
34+ this . fileData = { } ;
2235 }
2336
2437 /**
2538 * Sets the id of the attachment.
2639 *
2740 * @param id - The id of the attachment
2841 */
29- public setId ( id : Snowflake ) : this {
42+ public setId ( id : Snowflake | number ) : this {
3043 this . data . id = id ;
3144 return this ;
3245 }
@@ -85,6 +98,60 @@ export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
8598 return this ;
8699 }
87100
101+ /**
102+ * Sets the file data to upload with this attachment.
103+ *
104+ * @param data - The file data
105+ * @remarks Note that this data is NOT included in the {@link toJSON} output. To retrieve it, use {@link getRawFile}.
106+ */
107+ public setFileData ( data : Buffer | Uint8Array | string ) : this {
108+ this . fileData . data = data ;
109+ return this ;
110+ }
111+
112+ /**
113+ * Clears the file data from this attachment.
114+ */
115+ public clearFileData ( ) : this {
116+ this . fileData . data = undefined ;
117+ return this ;
118+ }
119+
120+ /**
121+ * Sets the content type of the file data to upload with this attachment.
122+ *
123+ * @remarks Note that this data is NOT included in the {@link toJSON} output. To retrieve it, use {@link getRawFile}.
124+ */
125+ public setFileContentType ( contentType : string ) : this {
126+ this . fileData . contentType = contentType ;
127+ return this ;
128+ }
129+
130+ /**
131+ * Clears the content type of the file data from this attachment.
132+ */
133+ public clearFileContentType ( ) : this {
134+ this . fileData . contentType = undefined ;
135+ return this ;
136+ }
137+
138+ /**
139+ * Converts this attachment to a {@link RawFile} for uploading.
140+ *
141+ * @returns A {@link RawFile} object, or `undefined` if no file data is set
142+ */
143+ public getRawFile ( ) : Partial < RawFile > | undefined {
144+ if ( ! this . fileData ?. data ) {
145+ return ;
146+ }
147+
148+ return {
149+ ...this . fileData ,
150+ name : this . data . filename ,
151+ key : this . data . id ? `files[${ this . data . id } ]` : undefined ,
152+ } ;
153+ }
154+
88155 /**
89156 * Sets the title of this attachment.
90157 *
0 commit comments