@discordjs/structures 0.2.0-dev.1752365789-3cff4d741

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1884 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/bitfields/BitField.ts
5
+ var BitField = class _BitField {
6
+ static {
7
+ __name(this, "BitField");
8
+ }
9
+ /**
10
+ * Numeric bit field flags.
11
+ *
12
+ * @remarks Defined in extension classes
13
+ */
14
+ static Flags = {};
15
+ static DefaultBit = 0n;
16
+ /**
17
+ * Bitfield of the packed bits
18
+ */
19
+ bitField;
20
+ /**
21
+ * @param bits - Bit(s) to read from
22
+ */
23
+ constructor(bits = this.constructor.DefaultBit) {
24
+ this.bitField = this.constructor.resolve(bits);
25
+ }
26
+ /**
27
+ * Checks whether the bit field has a bit, or any of multiple bits.
28
+ *
29
+ * @param bit - Bit(s) to check for
30
+ * @returns Whether the bit field has the bit(s)
31
+ */
32
+ any(bit) {
33
+ return (this.bitField & this.constructor.resolve(bit)) !== this.constructor.DefaultBit;
34
+ }
35
+ /**
36
+ * Checks if this bit field equals another
37
+ *
38
+ * @param bit - Bit(s) to check for
39
+ * @returns Whether this bit field equals the other
40
+ */
41
+ equals(bit) {
42
+ return this.bitField === this.constructor.resolve(bit);
43
+ }
44
+ /**
45
+ * Checks whether the bit field has a bit, or multiple bits.
46
+ *
47
+ * @param bit - Bit(s) to check for
48
+ * @returns Whether the bit field has the bit(s)
49
+ */
50
+ has(bit, ..._hasParams) {
51
+ const resolvedBit = this.constructor.resolve(bit);
52
+ return (this.bitField & resolvedBit) === resolvedBit;
53
+ }
54
+ /**
55
+ * Gets all given bits that are missing from the bit field.
56
+ *
57
+ * @param bits - Bit(s) to check for
58
+ * @param hasParams - Additional parameters for the has method, if any
59
+ * @returns A bit field containing the missing bits
60
+ */
61
+ missing(bits, ...hasParams) {
62
+ return new this.constructor(bits).remove(this).toArray(...hasParams);
63
+ }
64
+ /**
65
+ * Freezes these bits, making them immutable.
66
+ *
67
+ * @returns This bit field but frozen
68
+ */
69
+ freeze() {
70
+ return Object.freeze(this);
71
+ }
72
+ /**
73
+ * Adds bits to these ones.
74
+ *
75
+ * @param bits - Bits to add
76
+ * @returns These bits or new BitField if the instance is frozen.
77
+ */
78
+ add(...bits) {
79
+ let total = this.constructor.DefaultBit;
80
+ for (const bit of bits) {
81
+ total |= this.constructor.resolve(bit);
82
+ }
83
+ if (Object.isFrozen(this)) return new this.constructor(this.bitField | total);
84
+ this.bitField |= total;
85
+ return this;
86
+ }
87
+ /**
88
+ * Removes bits from these.
89
+ *
90
+ * @param bits - Bits to remove
91
+ * @returns These bits or new BitField if the instance is frozen.
92
+ */
93
+ remove(...bits) {
94
+ let total = this.constructor.DefaultBit;
95
+ for (const bit of bits) {
96
+ total |= this.constructor.resolve(bit);
97
+ }
98
+ if (Object.isFrozen(this)) return new this.constructor(this.bitField & ~total);
99
+ this.bitField &= ~total;
100
+ return this;
101
+ }
102
+ /**
103
+ * Gets an object mapping field names to a boolean indicating whether the bit is available.
104
+ *
105
+ * @param hasParams - Additional parameters for the has method, if any
106
+ * @returns An object mapping field names to a boolean indicating whether the bit is available
107
+ */
108
+ serialize(...hasParams) {
109
+ const serialized = {};
110
+ for (const [flag, bit] of Object.entries(this.constructor.Flags)) {
111
+ if (Number.isNaN(Number(flag))) serialized[flag] = this.has(bit, ...hasParams);
112
+ }
113
+ return serialized;
114
+ }
115
+ /**
116
+ * Gets an Array of bit field names based on the bits available.
117
+ *
118
+ * @param hasParams - Additional parameters for the has method, if any
119
+ * @returns An Array of bit field names
120
+ */
121
+ toArray(...hasParams) {
122
+ return [...this[Symbol.iterator](...hasParams)];
123
+ }
124
+ toJSON(asNumber) {
125
+ if (asNumber) {
126
+ if (this.bitField > Number.MAX_SAFE_INTEGER) {
127
+ throw new RangeError(
128
+ `Cannot convert bitfield value ${this.bitField} to number, as it is bigger than ${Number.MAX_SAFE_INTEGER} (the maximum safe integer)`
129
+ );
130
+ }
131
+ return Number(this.bitField);
132
+ }
133
+ return this.bitField.toString();
134
+ }
135
+ valueOf() {
136
+ return this.bitField;
137
+ }
138
+ *[Symbol.iterator](...hasParams) {
139
+ for (const bitName of Object.keys(this.constructor.Flags)) {
140
+ if (Number.isNaN(Number(bitName)) && this.has(bitName, ...hasParams)) yield bitName;
141
+ }
142
+ }
143
+ /**
144
+ * Resolves bit fields to their numeric form.
145
+ *
146
+ * @param bit - bit(s) to resolve
147
+ * @returns the numeric value of the bit fields
148
+ */
149
+ static resolve(bit) {
150
+ const DefaultBit = this.DefaultBit;
151
+ if (typeof bit === "bigint" && bit >= DefaultBit) return bit;
152
+ if (typeof bit === "number" && BigInt(bit) >= DefaultBit) return BigInt(bit);
153
+ if (bit instanceof _BitField) return bit.bitField;
154
+ if (Array.isArray(bit)) {
155
+ return bit.map((bit_) => this.resolve(bit_)).reduce((prev, bit_) => prev | bit_, DefaultBit);
156
+ }
157
+ if (typeof bit === "string") {
158
+ if (!Number.isNaN(Number(bit))) return BigInt(bit);
159
+ if (bit in this.Flags) return this.Flags[bit];
160
+ }
161
+ throw new Error(`BitFieldInvalid: ${JSON.stringify(bit)}`);
162
+ }
163
+ };
164
+
165
+ // src/bitfields/ChannelFlagsBitField.ts
166
+ import { ChannelFlags } from "discord-api-types/v10";
167
+ var ChannelFlagsBitField = class extends BitField {
168
+ static {
169
+ __name(this, "ChannelFlagsBitField");
170
+ }
171
+ /**
172
+ * Numeric guild channel flags.
173
+ */
174
+ static Flags = ChannelFlags;
175
+ toJSON() {
176
+ return super.toJSON(true);
177
+ }
178
+ };
179
+
180
+ // src/bitfields/PermissionsBitField.ts
181
+ import { PermissionFlagsBits } from "discord-api-types/v10";
182
+ var PermissionsBitField = class extends BitField {
183
+ static {
184
+ __name(this, "PermissionsBitField");
185
+ }
186
+ /**
187
+ * Numeric permission flags.
188
+ *
189
+ * @see {@link https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags}
190
+ */
191
+ static Flags = PermissionFlagsBits;
192
+ /**
193
+ * Bit field representing every permission combined
194
+ */
195
+ static All = Object.values(PermissionFlagsBits).reduce((all, perm) => all | perm, 0n);
196
+ /**
197
+ * Bit field representing the default permissions for users
198
+ */
199
+ static Default = 104324673n;
200
+ /**
201
+ * Bit field representing the permissions required for moderators of stage channels
202
+ */
203
+ static StageModerator = PermissionFlagsBits.ManageChannels | PermissionFlagsBits.MuteMembers | PermissionFlagsBits.MoveMembers;
204
+ /**
205
+ * Gets all given bits that are missing from the bit field.
206
+ *
207
+ * @param bits - Bit(s) to check for
208
+ * @param checkAdmin - Whether to allow the administrator permission to override
209
+ * @returns A bit field containing the missing permissions
210
+ */
211
+ missing(bits, checkAdmin = true) {
212
+ return checkAdmin && this.has(PermissionFlagsBits.Administrator) ? [] : super.missing(bits);
213
+ }
214
+ /**
215
+ * Checks whether the bit field has a permission, or any of multiple permissions.
216
+ *
217
+ * @param permission - Permission(s) to check for
218
+ * @param checkAdmin - Whether to allow the administrator permission to override
219
+ * @returns Whether the bit field has the permission(s)
220
+ */
221
+ any(permission, checkAdmin = true) {
222
+ return checkAdmin && super.has(PermissionFlagsBits.Administrator) || super.any(permission);
223
+ }
224
+ /**
225
+ * Checks whether the bit field has a permission, or multiple permissions.
226
+ *
227
+ * @param permission - Permission(s) to check for
228
+ * @param checkAdmin - Whether to allow the administrator permission to override
229
+ * @returns Whether the bit field has the permission(s)
230
+ */
231
+ has(permission, checkAdmin = true) {
232
+ return checkAdmin && super.has(PermissionFlagsBits.Administrator) || super.has(permission);
233
+ }
234
+ /**
235
+ * Gets an Array of bitfield names based on the permissions available.
236
+ *
237
+ * @returns An Array of permission names
238
+ */
239
+ toArray() {
240
+ return super.toArray(false);
241
+ }
242
+ };
243
+
244
+ // src/utils/symbols.ts
245
+ var kData = Symbol.for("djs.structures.data");
246
+ var kClone = Symbol.for("djs.structures.clone");
247
+ var kPatch = Symbol.for("djs.structures.patch");
248
+ var kExpiresTimestamp = Symbol.for("djs.structures.expiresTimestamp");
249
+ var kCreatedTimestamp = Symbol.for("djs.structures.createdTimestamp");
250
+ var kEditedTimestamp = Symbol.for("djs.structures.editedTimestamp");
251
+ var kArchiveTimestamp = Symbol.for("djs.structures.archiveTimestamp");
252
+ var kAllow = Symbol.for("djs.structures.allow");
253
+ var kDeny = Symbol.for("djs.structures.deny");
254
+ var kLastPinTimestamp = Symbol.for("djs.structures.lastPinTimestamp");
255
+ var kMixinConstruct = Symbol.for("djs.structures.mixin.construct");
256
+ var kMixinToJSON = Symbol.for("djs.structures.mixin.toJSON");
257
+
258
+ // src/channels/mixins/AppliedTagsMixin.ts
259
+ var AppliedTagsMixin = class {
260
+ static {
261
+ __name(this, "AppliedTagsMixin");
262
+ }
263
+ /**
264
+ * The ids of the set of tags that have been applied to a thread in a {@link (ForumChannel:class)} or a {@link (MediaChannel:class)}.
265
+ */
266
+ get appliedTags() {
267
+ return Array.isArray(this[kData].applied_tags) ? this[kData].applied_tags : null;
268
+ }
269
+ };
270
+
271
+ // src/channels/mixins/ChannelOwnerMixin.ts
272
+ var ChannelOwnerMixin = class {
273
+ static {
274
+ __name(this, "ChannelOwnerMixin");
275
+ }
276
+ /**
277
+ * The id of the creator of the group DM or thread
278
+ */
279
+ get ownerId() {
280
+ return this[kData].owner_id;
281
+ }
282
+ };
283
+
284
+ // src/channels/mixins/GuildChannelMixin.ts
285
+ import { channelLink } from "@discordjs/formatters";
286
+ var GuildChannelMixin = class {
287
+ static {
288
+ __name(this, "GuildChannelMixin");
289
+ }
290
+ /**
291
+ * The flags that are applied to the channel.
292
+ *
293
+ * @privateRemarks The type of `flags` can be narrowed in Guild Channels and DMChannel to ChannelFlags, and in GroupDM channel
294
+ * to null, respecting Omit behaviors
295
+ */
296
+ get flags() {
297
+ return this[kData].flags ? new ChannelFlagsBitField(this[kData].flags) : null;
298
+ }
299
+ /**
300
+ * THe id of the guild this channel is in.
301
+ */
302
+ get guildId() {
303
+ return this[kData].guild_id;
304
+ }
305
+ /**
306
+ * The URL to this channel.
307
+ */
308
+ get url() {
309
+ return channelLink(this.id, this.guildId);
310
+ }
311
+ /**
312
+ * Indicates whether this channel is in a guild
313
+ */
314
+ isGuildBased() {
315
+ return true;
316
+ }
317
+ };
318
+
319
+ // src/channels/mixins/ChannelParentMixin.ts
320
+ var ChannelParentMixin = class extends GuildChannelMixin {
321
+ static {
322
+ __name(this, "ChannelParentMixin");
323
+ }
324
+ /**
325
+ * The id of the parent category for a channel (each parent category can contain up to 50 channels) or id of the parent channel for a thread
326
+ */
327
+ get parentId() {
328
+ return this[kData].parent_id;
329
+ }
330
+ /**
331
+ * Whether the channel is nsfw
332
+ */
333
+ get nsfw() {
334
+ return this[kData].nsfw;
335
+ }
336
+ };
337
+
338
+ // src/channels/mixins/ChannelPermissionMixin.ts
339
+ var ChannelPermissionMixin = class {
340
+ static {
341
+ __name(this, "ChannelPermissionMixin");
342
+ }
343
+ /**
344
+ * The sorting position of the channel
345
+ */
346
+ get position() {
347
+ return this[kData].position;
348
+ }
349
+ /**
350
+ * Indicates whether this channel can have permission overwrites
351
+ */
352
+ isPermissionCapable() {
353
+ return true;
354
+ }
355
+ };
356
+
357
+ // src/channels/mixins/ChannelPinMixin.ts
358
+ var ChannelPinMixin = class {
359
+ static {
360
+ __name(this, "ChannelPinMixin");
361
+ }
362
+ /**
363
+ * The template used for removing data from the raw data stored for each Channel.
364
+ */
365
+ static DataTemplate = {
366
+ set last_pin_timestamp(_) {
367
+ }
368
+ };
369
+ [kMixinConstruct]() {
370
+ this[kLastPinTimestamp] ??= null;
371
+ }
372
+ /**
373
+ * {@inheritDoc Structure.optimizeData}
374
+ */
375
+ optimizeData(data) {
376
+ if (data.last_pin_timestamp) {
377
+ this[kLastPinTimestamp] = Date.parse(data.last_pin_timestamp);
378
+ }
379
+ }
380
+ /**
381
+ * The timestamp of when the last pin in the channel happened.
382
+ */
383
+ get lastPinTimestamp() {
384
+ return this[kLastPinTimestamp];
385
+ }
386
+ /**
387
+ * The Date of when the last pin in the channel happened
388
+ */
389
+ get lastPinAt() {
390
+ const lastPinTimestamp = this.lastPinTimestamp;
391
+ return lastPinTimestamp ? new Date(lastPinTimestamp) : null;
392
+ }
393
+ /**
394
+ * Adds data from optimized properties omitted from [kData].
395
+ *
396
+ * @param data - the result of {@link (Structure:class).toJSON}
397
+ */
398
+ [kMixinToJSON](data) {
399
+ data.last_pin_timestamp = this[kLastPinTimestamp] ? new Date(this[kLastPinTimestamp]).toISOString() : null;
400
+ }
401
+ };
402
+
403
+ // src/channels/mixins/TextChannelMixin.ts
404
+ var TextChannelMixin = class {
405
+ static {
406
+ __name(this, "TextChannelMixin");
407
+ }
408
+ /**
409
+ * The id of the last message sent in this channel.
410
+ */
411
+ get lastMessageId() {
412
+ return this[kData].last_message_id;
413
+ }
414
+ /**
415
+ * Indicates whether this channel can contain messages
416
+ */
417
+ isTextBased() {
418
+ return true;
419
+ }
420
+ };
421
+
422
+ // src/channels/mixins/ChannelSlowmodeMixin.ts
423
+ var ChannelSlowmodeMixin = class extends TextChannelMixin {
424
+ static {
425
+ __name(this, "ChannelSlowmodeMixin");
426
+ }
427
+ /**
428
+ * The rate limit per user (slowmode) of this channel.
429
+ */
430
+ get rateLimitPerUser() {
431
+ return this[kData].rate_limit_per_user;
432
+ }
433
+ };
434
+
435
+ // src/channels/mixins/ChannelWebhookMixin.ts
436
+ var ChannelWebhookMixin = class {
437
+ static {
438
+ __name(this, "ChannelWebhookMixin");
439
+ }
440
+ /**
441
+ * Indicates whether this channel can have webhooks
442
+ */
443
+ isWebhookCapable() {
444
+ return true;
445
+ }
446
+ };
447
+
448
+ // src/channels/mixins/ChannelTopicMixin.ts
449
+ var ChannelTopicMixin = class extends ChannelWebhookMixin {
450
+ static {
451
+ __name(this, "ChannelTopicMixin");
452
+ }
453
+ /**
454
+ * The topic of this channel.
455
+ */
456
+ get topic() {
457
+ return this[kData].topic;
458
+ }
459
+ /**
460
+ * The duration after which new threads get archived by default on this channel.
461
+ */
462
+ get defaultAutoArchiveDuration() {
463
+ return this[kData].default_auto_archive_duration;
464
+ }
465
+ /**
466
+ * The default value for rate limit per user (slowmode) on new threads in this channel.
467
+ */
468
+ get defaultThreadRateLimitPerUser() {
469
+ return this[kData].default_thread_rate_limit_per_user;
470
+ }
471
+ };
472
+
473
+ // src/channels/mixins/DMChannelMixin.ts
474
+ import { channelLink as channelLink2 } from "@discordjs/formatters";
475
+ var DMChannelMixin = class {
476
+ static {
477
+ __name(this, "DMChannelMixin");
478
+ }
479
+ /**
480
+ * The URL to this channel.
481
+ */
482
+ get url() {
483
+ return channelLink2(this.id);
484
+ }
485
+ /**
486
+ * Indicates whether this channel is a DM or DM Group
487
+ */
488
+ isDMBased() {
489
+ return true;
490
+ }
491
+ };
492
+
493
+ // src/channels/mixins/GroupDMMixin.ts
494
+ var GroupDMMixin = class {
495
+ static {
496
+ __name(this, "GroupDMMixin");
497
+ }
498
+ /**
499
+ * The icon hash of the group DM.
500
+ */
501
+ get icon() {
502
+ return this[kData].icon;
503
+ }
504
+ /**
505
+ * Whether the channel is managed by an application via the `gdm.join` OAuth2 scope.
506
+ */
507
+ get managed() {
508
+ return this[kData].managed;
509
+ }
510
+ /**
511
+ * The application id of the group DM creator if it is bot-created.
512
+ */
513
+ get applicationId() {
514
+ return this[kData].application_id;
515
+ }
516
+ };
517
+
518
+ // src/channels/mixins/ThreadChannelMixin.ts
519
+ var ThreadChannelMixin = class {
520
+ static {
521
+ __name(this, "ThreadChannelMixin");
522
+ }
523
+ /**
524
+ * The approximate count of users in a thread, stops counting at 50
525
+ */
526
+ get memberCount() {
527
+ return this[kData].member_count;
528
+ }
529
+ /**
530
+ * The number of messages (not including the initial message or deleted messages) in a thread.
531
+ */
532
+ get messageCount() {
533
+ return this[kData].message_count;
534
+ }
535
+ /**
536
+ * The number of messages ever sent in a thread, it's similar to message_count on message creation,
537
+ * but will not decrement the number when a message is deleted.
538
+ */
539
+ get totalMessageSent() {
540
+ return this[kData].total_message_sent;
541
+ }
542
+ /**
543
+ * Indicates whether this channel is a thread channel
544
+ */
545
+ isThread() {
546
+ return true;
547
+ }
548
+ };
549
+
550
+ // src/channels/mixins/ThreadOnlyChannelMixin.ts
551
+ var ThreadOnlyChannelMixin = class {
552
+ static {
553
+ __name(this, "ThreadOnlyChannelMixin");
554
+ }
555
+ /**
556
+ * The emoji to show in the add reaction button on a thread in this channel.
557
+ */
558
+ get defaultReactionEmoji() {
559
+ return this[kData].default_reaction_emoji;
560
+ }
561
+ /**
562
+ * The default sort order type used to order posts in this channel.
563
+ *
564
+ * @defaultValue `null` – indicates a preferred sort order hasn't been set.
565
+ */
566
+ get defaultSortOrder() {
567
+ return this[kData].default_sort_order;
568
+ }
569
+ /**
570
+ * Indicates whether this channel only allows thread creation
571
+ */
572
+ isThreadOnly() {
573
+ return true;
574
+ }
575
+ };
576
+
577
+ // src/channels/mixins/VoiceChannelMixin.ts
578
+ var VoiceChannelMixin = class extends TextChannelMixin {
579
+ static {
580
+ __name(this, "VoiceChannelMixin");
581
+ }
582
+ /**
583
+ * The bitrate (in bits) of the voice channel.
584
+ */
585
+ get bitrate() {
586
+ return this[kData].bitrate;
587
+ }
588
+ /**
589
+ * The voice region id for this channel, automatic when set to null.
590
+ */
591
+ get rtcRegion() {
592
+ return this[kData].rtc_region;
593
+ }
594
+ /**
595
+ * The camera video quality mode of the voice channel, {@link discord-api-types/v10#(VideoQualityMode:enum) | Auto} when not present.
596
+ */
597
+ get videoQualityMode() {
598
+ return this[kData].video_quality_mode;
599
+ }
600
+ /**
601
+ * The user limit of the voice channel.
602
+ */
603
+ get userLimit() {
604
+ return this[kData].user_limit;
605
+ }
606
+ /**
607
+ * Indicates whether this channel has voice connection capabilities
608
+ */
609
+ isVoiceBased() {
610
+ return true;
611
+ }
612
+ };
613
+
614
+ // src/Structure.ts
615
+ var DataTemplatePropertyName = "DataTemplate";
616
+ var OptimizeDataPropertyName = "optimizeData";
617
+ var Structure = class {
618
+ static {
619
+ __name(this, "Structure");
620
+ }
621
+ /**
622
+ * The template used for removing data from the raw data stored for each Structure.
623
+ *
624
+ * @remarks This template should be overridden in all subclasses to provide more accurate type information.
625
+ * The template in the base {@link Structure} class will have no effect on most subclasses for this reason.
626
+ */
627
+ static DataTemplate = {};
628
+ /**
629
+ * @returns A cloned version of the data template, ready to create a new data object.
630
+ */
631
+ getDataTemplate() {
632
+ return Object.create(this.constructor.DataTemplate);
633
+ }
634
+ /**
635
+ * The raw data from the API for this structure
636
+ *
637
+ * @internal
638
+ */
639
+ [kData];
640
+ /**
641
+ * Creates a new structure to represent API data
642
+ *
643
+ * @param data - the data from the API that this structure will represent
644
+ * @remarks To be made public in subclasses
645
+ * @internal
646
+ */
647
+ constructor(data, ..._rest) {
648
+ this[kData] = Object.assign(this.getDataTemplate(), data);
649
+ this[kMixinConstruct]?.(data);
650
+ }
651
+ /**
652
+ * Patches the raw data of this object in place
653
+ *
654
+ * @param data - the updated data from the API to patch with
655
+ * @remarks To be made public in subclasses
656
+ * @returns this
657
+ * @internal
658
+ */
659
+ [kPatch](data) {
660
+ this[kData] = Object.assign(this.getDataTemplate(), this[kData], data);
661
+ this.optimizeData(data);
662
+ return this;
663
+ }
664
+ /**
665
+ * Creates a clone of this structure
666
+ *
667
+ * @returns a clone of this
668
+ * @internal
669
+ */
670
+ [kClone](patchPayload) {
671
+ const clone = this.toJSON();
672
+ return new this.constructor(
673
+ // Ensure the ts-expect-error only applies to the constructor call
674
+ patchPayload ? Object.assign(clone, patchPayload) : clone
675
+ );
676
+ }
677
+ /**
678
+ * Function called to ensure stored raw data is in optimized formats, used in tandem with a data template
679
+ *
680
+ * @example created_timestamp is an ISO string, this can be stored in optimized form as a number
681
+ * @param _data - the raw data received from the API to optimize
682
+ * @remarks Implementation to be done in subclasses and mixins where needed.
683
+ * For typescript users, mixins must use the closest ancestors access modifier.
684
+ * @remarks Automatically called in Structure[kPatch] but must be called manually in the constructor
685
+ * of any class implementing this method.
686
+ * @remarks Additionally, when implementing, ensure to call `super._optimizeData` if any class in the super chain aside
687
+ * from Structure contains an implementation.
688
+ * Note: mixins do not need to call super ever as the process of mixing walks the prototype chain.
689
+ * @virtual
690
+ * @internal
691
+ */
692
+ optimizeData(_data) {
693
+ }
694
+ /**
695
+ * Transforms this object to its JSON format with raw API data (or close to it),
696
+ * automatically called by `JSON.stringify()` when this structure is stringified
697
+ *
698
+ * @remarks
699
+ * The type of this data is determined by omissions at runtime and is only guaranteed for default omissions
700
+ * @privateRemarks
701
+ * When omitting properties at the library level, this must be overridden to re-add those properties
702
+ */
703
+ toJSON() {
704
+ const data = (
705
+ // Spread is way faster than structuredClone, but is shallow. So use it only if there is no nested objects
706
+ Object.values(this[kData]).some((value) => typeof value === "object" && value !== null) ? structuredClone(this[kData]) : { ...this[kData] }
707
+ );
708
+ this[kMixinToJSON]?.(data);
709
+ return data;
710
+ }
711
+ };
712
+
713
+ // src/channels/ForumTag.ts
714
+ var ForumTag = class extends Structure {
715
+ static {
716
+ __name(this, "ForumTag");
717
+ }
718
+ constructor(data) {
719
+ super(data);
720
+ }
721
+ /**
722
+ * The id of the tag.
723
+ */
724
+ get id() {
725
+ return this[kData].id;
726
+ }
727
+ /**
728
+ * The name of the tag.
729
+ */
730
+ get name() {
731
+ return this[kData].name;
732
+ }
733
+ /**
734
+ * Whether this tag can only be added to or removed from threads by a member with the {@link discord-api-types/v10#(PermissionFlagsBits:variable) | ManageThreads} permission.
735
+ */
736
+ get moderated() {
737
+ return this[kData].moderated;
738
+ }
739
+ /**
740
+ * The id of a guild's custom emoji.
741
+ */
742
+ get emojiId() {
743
+ return this[kData].emoji_id;
744
+ }
745
+ /**
746
+ * The unicode character of the emoji.
747
+ */
748
+ get emojiName() {
749
+ return this[kData].emoji_name;
750
+ }
751
+ /**
752
+ * The textual representation of this tag's emoji. Either a unicode character or a guild emoji mention.
753
+ */
754
+ get emoji() {
755
+ return this.emojiName ?? `<:_:${this.emojiId}>`;
756
+ }
757
+ };
758
+
759
+ // src/channels/PermissionOverwrite.ts
760
+ var PermissionOverwrite = class extends Structure {
761
+ static {
762
+ __name(this, "PermissionOverwrite");
763
+ }
764
+ [kAllow] = null;
765
+ [kDeny] = null;
766
+ constructor(data) {
767
+ super(data);
768
+ this.optimizeData(data);
769
+ }
770
+ /**
771
+ * The template used for removing data from the raw data stored for each ThreadMetadata
772
+ *
773
+ * @remarks This template has defaults, if you want to remove additional data and keep the defaults,
774
+ * use `Object.defineProperties`. To override the defaults, set this value directly.
775
+ */
776
+ static DataTemplate = {
777
+ set allow(_) {
778
+ },
779
+ set deny(_) {
780
+ }
781
+ };
782
+ /**
783
+ * {@inheritDoc Structure.optimizeData}
784
+ */
785
+ optimizeData(data) {
786
+ if (data.allow) {
787
+ this[kAllow] = BigInt(data.allow);
788
+ }
789
+ if (data.deny) {
790
+ this[kDeny] = BigInt(data.deny);
791
+ }
792
+ }
793
+ /**
794
+ * The permission bit set allowed by this overwrite.
795
+ */
796
+ get allow() {
797
+ const allow = this[kAllow];
798
+ return typeof allow === "bigint" ? new PermissionsBitField(allow) : null;
799
+ }
800
+ /**
801
+ * The permission bit set denied by this overwrite.
802
+ */
803
+ get deny() {
804
+ const deny = this[kDeny];
805
+ return typeof deny === "bigint" ? new PermissionsBitField(deny) : null;
806
+ }
807
+ /**
808
+ * The role or user id for this overwrite.
809
+ */
810
+ get id() {
811
+ return this[kData].id;
812
+ }
813
+ /**
814
+ * The type of this overwrite.
815
+ */
816
+ get type() {
817
+ return this[kData].type;
818
+ }
819
+ /**
820
+ * {@inheritDoc Structure.toJSON}
821
+ */
822
+ toJSON() {
823
+ const clone = super.toJSON();
824
+ if (this[kAllow]) {
825
+ clone.allow = this[kAllow].toString();
826
+ }
827
+ if (this[kDeny]) {
828
+ clone.deny = this[kDeny].toString();
829
+ }
830
+ return clone;
831
+ }
832
+ };
833
+
834
+ // src/channels/ThreadMetadata.ts
835
+ var ThreadMetadata = class extends Structure {
836
+ static {
837
+ __name(this, "ThreadMetadata");
838
+ }
839
+ [kArchiveTimestamp] = null;
840
+ [kCreatedTimestamp] = null;
841
+ constructor(data) {
842
+ super(data);
843
+ this.optimizeData(data);
844
+ }
845
+ /**
846
+ * The template used for removing data from the raw data stored for each ThreadMetadata
847
+ *
848
+ * @remarks This template has defaults, if you want to remove additional data and keep the defaults,
849
+ * use `Object.defineProperties`. To override the defaults, set this value directly.
850
+ */
851
+ static DataTemplate = {
852
+ set create_timestamp(_) {
853
+ },
854
+ set archive_timestamp(_) {
855
+ }
856
+ };
857
+ /**
858
+ * {@inheritDoc Structure.optimizeData}
859
+ */
860
+ optimizeData(data) {
861
+ if (data.create_timestamp) {
862
+ this[kCreatedTimestamp] = Date.parse(data.create_timestamp);
863
+ }
864
+ if (data.archive_timestamp) {
865
+ this[kArchiveTimestamp] = Date.parse(data.archive_timestamp);
866
+ }
867
+ }
868
+ /**
869
+ * Whether the thread is archived.
870
+ */
871
+ get archived() {
872
+ return this[kData].archived;
873
+ }
874
+ /**
875
+ * The timestamp when the thread's archive status was last changed, used for calculating recent activity.
876
+ */
877
+ get archivedTimestamp() {
878
+ return this[kArchiveTimestamp];
879
+ }
880
+ /**
881
+ * The timestamp when the thread was created; only populated for threads created after 2022-01-09.
882
+ */
883
+ get createdTimestamp() {
884
+ return this[kCreatedTimestamp];
885
+ }
886
+ /**
887
+ * The thread will stop showing in the channel list after auto_archive_duration minutes of inactivity,
888
+ */
889
+ get autoArchiveDuration() {
890
+ return this[kData].auto_archive_duration;
891
+ }
892
+ /**
893
+ * Whether non-moderators can add other non-moderators to a thread; only available on private threads.
894
+ */
895
+ get invitable() {
896
+ return this[kData].invitable;
897
+ }
898
+ /**
899
+ * Whether the thread is locked; when a thread is locked, only users with {@link discord-api-types/v10#(PermissionFlagsBits:variable) | ManageThreads} can unarchive it.
900
+ */
901
+ get locked() {
902
+ return this[kData].locked;
903
+ }
904
+ /**
905
+ * The time the thread was archived at
906
+ */
907
+ get archivedAt() {
908
+ const archivedTimestamp = this.archivedTimestamp;
909
+ return archivedTimestamp ? new Date(archivedTimestamp) : null;
910
+ }
911
+ /**
912
+ * The time the thread was created at
913
+ */
914
+ get createdAt() {
915
+ const createdTimestamp = this.createdTimestamp;
916
+ return createdTimestamp ? new Date(createdTimestamp) : null;
917
+ }
918
+ /**
919
+ * {@inheritDoc Structure.toJSON}
920
+ */
921
+ toJSON() {
922
+ const data = super.toJSON();
923
+ if (this[kArchiveTimestamp]) {
924
+ data.archive_timestamp = new Date(this[kArchiveTimestamp]).toISOString();
925
+ }
926
+ if (this[kCreatedTimestamp]) {
927
+ data.create_timestamp = new Date(this[kCreatedTimestamp]).toISOString();
928
+ }
929
+ return data;
930
+ }
931
+ };
932
+
933
+ // src/channels/Channel.ts
934
+ import { DiscordSnowflake } from "@sapphire/snowflake";
935
+
936
+ // src/utils/type-guards.ts
937
+ function isIdSet(id) {
938
+ return typeof id === "string" || typeof id === "bigint";
939
+ }
940
+ __name(isIdSet, "isIdSet");
941
+
942
+ // src/channels/Channel.ts
943
+ var Channel = class extends Structure {
944
+ static {
945
+ __name(this, "Channel");
946
+ }
947
+ /**
948
+ * The template used for removing data from the raw data stored for each Channel.
949
+ *
950
+ * @remarks This template is only guaranteed to apply to channels constructed directly via `new Channel()`.
951
+ * Use the appropriate subclass template to remove data from that channel type.
952
+ */
953
+ static DataTemplate = {};
954
+ /**
955
+ * @param data - The raw data received from the API for the channel
956
+ */
957
+ constructor(data) {
958
+ super(data);
959
+ }
960
+ /**
961
+ * {@inheritDoc Structure.[kPatch]}
962
+ *
963
+ * @internal
964
+ */
965
+ [kPatch](data) {
966
+ return super[kPatch](data);
967
+ }
968
+ /**
969
+ * The id of the channel
970
+ */
971
+ get id() {
972
+ return this[kData].id;
973
+ }
974
+ /**
975
+ * The type of the channel
976
+ */
977
+ get type() {
978
+ return this[kData].type;
979
+ }
980
+ /**
981
+ * The name of the channel, null for DMs
982
+ *
983
+ * @privateRemarks The type of `name` can be narrowed in Guild Channels and DM channels to string and null respectively,
984
+ * respecting Omit behaviors
985
+ */
986
+ get name() {
987
+ return this[kData].name;
988
+ }
989
+ /**
990
+ * The flags that are applied to the channel.
991
+ *
992
+ * @privateRemarks The type of `flags` can be narrowed in Guild Channels and DMChannel to ChannelFlags, and in GroupDM channel
993
+ * to null, respecting Omit behaviors
994
+ */
995
+ get flags() {
996
+ const flags = "flags" in this[kData] && typeof this[kData].flags === "number" ? this[kData].flags : null;
997
+ return flags ? new ChannelFlagsBitField(flags) : null;
998
+ }
999
+ /**
1000
+ * The timestamp the channel was created at
1001
+ */
1002
+ get createdTimestamp() {
1003
+ return isIdSet(this.id) ? DiscordSnowflake.timestampFrom(this.id) : null;
1004
+ }
1005
+ /**
1006
+ * The time the channel was created at
1007
+ */
1008
+ get createdAt() {
1009
+ const createdTimestamp = this.createdTimestamp;
1010
+ return createdTimestamp ? new Date(createdTimestamp) : null;
1011
+ }
1012
+ /**
1013
+ * Indicates whether this channel is a thread channel
1014
+ *
1015
+ * @privateRemarks Overridden to `true` on `ThreadChannelMixin`
1016
+ */
1017
+ isThread() {
1018
+ return false;
1019
+ }
1020
+ /**
1021
+ * Indicates whether this channel can contain messages
1022
+ *
1023
+ * @privateRemarks Overridden to `true` on `TextChannelMixin`
1024
+ */
1025
+ isTextBased() {
1026
+ return false;
1027
+ }
1028
+ /**
1029
+ * Indicates whether this channel is in a guild
1030
+ *
1031
+ * @privateRemarks Overridden to `true` on `GuildChannelMixin`
1032
+ */
1033
+ isGuildBased() {
1034
+ return false;
1035
+ }
1036
+ /**
1037
+ * Indicates whether this channel is a DM or DM Group
1038
+ *
1039
+ * @privateRemarks Overridden to `true` on `DMChannelMixin`
1040
+ */
1041
+ isDMBased() {
1042
+ return false;
1043
+ }
1044
+ /**
1045
+ * Indicates whether this channel has voice connection capabilities
1046
+ *
1047
+ * @privateRemarks Overridden to `true` on `VoiceChannelMixin`
1048
+ */
1049
+ isVoiceBased() {
1050
+ return false;
1051
+ }
1052
+ /**
1053
+ * Indicates whether this channel only allows thread creation
1054
+ *
1055
+ * @privateRemarks Overridden to `true` on `ThreadOnlyChannelMixin`
1056
+ */
1057
+ isThreadOnly() {
1058
+ return false;
1059
+ }
1060
+ /**
1061
+ * Indicates whether this channel can have permission overwrites
1062
+ *
1063
+ * @privateRemarks Overridden to `true` on `ChannelPermissionsMixin`
1064
+ */
1065
+ isPermissionCapable() {
1066
+ return false;
1067
+ }
1068
+ /**
1069
+ * Indicates whether this channel can have webhooks
1070
+ *
1071
+ * @privateRemarks Overridden to `true` on `ChannelWebhooksMixin`
1072
+ */
1073
+ isWebhookCapable() {
1074
+ return false;
1075
+ }
1076
+ };
1077
+
1078
+ // src/Mixin.ts
1079
+ function Mixin(destination, mixins) {
1080
+ const dataTemplates = [];
1081
+ const dataOptimizations = [];
1082
+ const enrichToJSONs = [];
1083
+ const constructors = [];
1084
+ for (const mixin of mixins) {
1085
+ const prototypeChain = [];
1086
+ let extendedClass = mixin;
1087
+ while (extendedClass.prototype !== void 0) {
1088
+ if (DataTemplatePropertyName in extendedClass && typeof extendedClass.DataTemplate === "object" && // eslint-disable-next-line no-eq-null, eqeqeq
1089
+ extendedClass.DataTemplate != null) {
1090
+ dataTemplates.push(extendedClass.DataTemplate);
1091
+ }
1092
+ prototypeChain.unshift(extendedClass.prototype);
1093
+ extendedClass = Object.getPrototypeOf(extendedClass);
1094
+ }
1095
+ for (const prototype of prototypeChain) {
1096
+ if (prototype[kMixinConstruct]) {
1097
+ constructors.push(prototype[kMixinConstruct]);
1098
+ }
1099
+ if (prototype[kMixinToJSON]) {
1100
+ enrichToJSONs.push(prototype[kMixinToJSON]);
1101
+ }
1102
+ const originalDescriptors = Object.getOwnPropertyDescriptors(prototype);
1103
+ const usingDescriptors = {};
1104
+ for (const [prop, descriptor] of Object.entries(originalDescriptors)) {
1105
+ if (["constructor"].includes(prop)) {
1106
+ continue;
1107
+ }
1108
+ if (prop === OptimizeDataPropertyName) {
1109
+ if (typeof descriptor.value !== "function")
1110
+ throw new RangeError(`Expected ${prop} to be a function, received ${typeof descriptor.value} instead.`);
1111
+ dataOptimizations.push(descriptor.value);
1112
+ continue;
1113
+ }
1114
+ if (typeof descriptor.get !== "undefined" || typeof descriptor.set !== "undefined" || typeof descriptor.value === "function") {
1115
+ usingDescriptors[prop] = descriptor;
1116
+ }
1117
+ }
1118
+ Object.defineProperties(destination.prototype, usingDescriptors);
1119
+ }
1120
+ }
1121
+ if (constructors.length > 0) {
1122
+ Object.defineProperty(destination.prototype, kMixinConstruct, {
1123
+ writable: true,
1124
+ enumerable: false,
1125
+ configurable: true,
1126
+ // eslint-disable-next-line func-name-matching
1127
+ value: /* @__PURE__ */ __name(function _mixinConstructors(data) {
1128
+ for (const construct of constructors) {
1129
+ construct.call(this, data);
1130
+ }
1131
+ }, "_mixinConstructors")
1132
+ });
1133
+ }
1134
+ const baseOptimize = Object.getOwnPropertyDescriptor(destination, OptimizeDataPropertyName);
1135
+ if (baseOptimize && typeof baseOptimize.value === "function") {
1136
+ dataOptimizations.push(baseOptimize.value);
1137
+ }
1138
+ const superOptimize = Object.getOwnPropertyDescriptor(
1139
+ Object.getPrototypeOf(destination).prototype,
1140
+ OptimizeDataPropertyName
1141
+ );
1142
+ if (!baseOptimize && superOptimize && typeof superOptimize.value === "function") {
1143
+ dataOptimizations.unshift(superOptimize.value);
1144
+ }
1145
+ if (dataOptimizations.length > 1 || dataOptimizations.length === 1 && !baseOptimize) {
1146
+ Object.defineProperty(destination.prototype, OptimizeDataPropertyName, {
1147
+ writable: true,
1148
+ enumerable: false,
1149
+ configurable: true,
1150
+ // eslint-disable-next-line func-name-matching
1151
+ value: /* @__PURE__ */ __name(function _mixinOptimizeData(data) {
1152
+ for (const optimization of dataOptimizations) {
1153
+ optimization.call(this, data);
1154
+ }
1155
+ }, "_mixinOptimizeData")
1156
+ });
1157
+ }
1158
+ if (enrichToJSONs.length > 0) {
1159
+ Object.defineProperty(destination.prototype, kMixinToJSON, {
1160
+ writable: true,
1161
+ enumerable: false,
1162
+ configurable: true,
1163
+ // eslint-disable-next-line func-name-matching
1164
+ value: /* @__PURE__ */ __name(function _mixinToJSON(data) {
1165
+ for (const enricher of enrichToJSONs) {
1166
+ enricher.call(this, data);
1167
+ }
1168
+ }, "_mixinToJSON")
1169
+ });
1170
+ }
1171
+ if (dataTemplates.length > 0) {
1172
+ if (!Object.getOwnPropertyDescriptor(destination, DataTemplatePropertyName)) {
1173
+ Object.defineProperty(destination, DataTemplatePropertyName, {
1174
+ value: Object.defineProperties({}, Object.getOwnPropertyDescriptors(destination[DataTemplatePropertyName])),
1175
+ writable: true,
1176
+ enumerable: true,
1177
+ configurable: true
1178
+ });
1179
+ }
1180
+ for (const template of dataTemplates) {
1181
+ Object.defineProperties(destination[DataTemplatePropertyName], Object.getOwnPropertyDescriptors(template));
1182
+ }
1183
+ }
1184
+ }
1185
+ __name(Mixin, "Mixin");
1186
+
1187
+ // src/channels/AnnouncementChannel.ts
1188
+ var AnnouncementChannel = class extends Channel {
1189
+ static {
1190
+ __name(this, "AnnouncementChannel");
1191
+ }
1192
+ constructor(data) {
1193
+ super(data);
1194
+ this.optimizeData(data);
1195
+ }
1196
+ };
1197
+ Mixin(AnnouncementChannel, [
1198
+ TextChannelMixin,
1199
+ ChannelParentMixin,
1200
+ ChannelPermissionMixin,
1201
+ ChannelPinMixin,
1202
+ ChannelSlowmodeMixin,
1203
+ ChannelTopicMixin
1204
+ ]);
1205
+
1206
+ // src/channels/AnnouncementThreadChannel.ts
1207
+ var AnnouncementThreadChannel = class extends Channel {
1208
+ static {
1209
+ __name(this, "AnnouncementThreadChannel");
1210
+ }
1211
+ constructor(data) {
1212
+ super(data);
1213
+ this.optimizeData?.(data);
1214
+ }
1215
+ };
1216
+ Mixin(AnnouncementThreadChannel, [
1217
+ TextChannelMixin,
1218
+ ChannelOwnerMixin,
1219
+ ChannelParentMixin,
1220
+ ChannelPinMixin,
1221
+ ChannelSlowmodeMixin,
1222
+ GuildChannelMixin,
1223
+ ThreadChannelMixin
1224
+ ]);
1225
+
1226
+ // src/channels/CategoryChannel.ts
1227
+ var CategoryChannel = class extends Channel {
1228
+ static {
1229
+ __name(this, "CategoryChannel");
1230
+ }
1231
+ constructor(data) {
1232
+ super(data);
1233
+ this.optimizeData(data);
1234
+ }
1235
+ };
1236
+ Mixin(CategoryChannel, [ChannelPermissionMixin, GuildChannelMixin]);
1237
+
1238
+ // src/channels/DMChannel.ts
1239
+ var DMChannel = class extends Channel {
1240
+ static {
1241
+ __name(this, "DMChannel");
1242
+ }
1243
+ constructor(data) {
1244
+ super(data);
1245
+ this.optimizeData(data);
1246
+ }
1247
+ };
1248
+ Mixin(DMChannel, [DMChannelMixin, TextChannelMixin, ChannelPinMixin]);
1249
+
1250
+ // src/channels/ForumChannel.ts
1251
+ var ForumChannel = class extends Channel {
1252
+ static {
1253
+ __name(this, "ForumChannel");
1254
+ }
1255
+ constructor(data) {
1256
+ super(data);
1257
+ this.optimizeData(data);
1258
+ }
1259
+ /**
1260
+ * The default forum layout view used to display posts in this channel.
1261
+ * Defaults to 0, which indicates a layout view has not been set by a channel admin.
1262
+ */
1263
+ get defaultForumLayout() {
1264
+ return this[kData].default_forum_layout;
1265
+ }
1266
+ };
1267
+ Mixin(ForumChannel, [ChannelParentMixin, ChannelPermissionMixin, ChannelTopicMixin, ThreadOnlyChannelMixin]);
1268
+
1269
+ // src/channels/GroupDMChannel.ts
1270
+ var GroupDMChannel = class extends Channel {
1271
+ static {
1272
+ __name(this, "GroupDMChannel");
1273
+ }
1274
+ constructor(data) {
1275
+ super(data);
1276
+ this.optimizeData(data);
1277
+ }
1278
+ };
1279
+ Mixin(GroupDMChannel, [DMChannelMixin, TextChannelMixin, ChannelOwnerMixin, GroupDMMixin]);
1280
+
1281
+ // src/channels/MediaChannel.ts
1282
+ var MediaChannel = class extends Channel {
1283
+ static {
1284
+ __name(this, "MediaChannel");
1285
+ }
1286
+ constructor(data) {
1287
+ super(data);
1288
+ this.optimizeData(data);
1289
+ }
1290
+ };
1291
+ Mixin(MediaChannel, [ChannelParentMixin, ChannelPermissionMixin, ChannelTopicMixin, ThreadOnlyChannelMixin]);
1292
+
1293
+ // src/channels/PrivateThreadChannel.ts
1294
+ var PrivateThreadChannel = class extends Channel {
1295
+ static {
1296
+ __name(this, "PrivateThreadChannel");
1297
+ }
1298
+ constructor(data) {
1299
+ super(data);
1300
+ this.optimizeData(data);
1301
+ }
1302
+ };
1303
+ Mixin(PrivateThreadChannel, [
1304
+ TextChannelMixin,
1305
+ ChannelOwnerMixin,
1306
+ ChannelParentMixin,
1307
+ ChannelPinMixin,
1308
+ ChannelSlowmodeMixin,
1309
+ ThreadChannelMixin
1310
+ ]);
1311
+
1312
+ // src/channels/PublicThreadChannel.ts
1313
+ var PublicThreadChannel = class extends Channel {
1314
+ static {
1315
+ __name(this, "PublicThreadChannel");
1316
+ }
1317
+ constructor(data) {
1318
+ super(data);
1319
+ this.optimizeData(data);
1320
+ }
1321
+ };
1322
+ Mixin(PublicThreadChannel, [
1323
+ TextChannelMixin,
1324
+ ChannelOwnerMixin,
1325
+ ChannelParentMixin,
1326
+ ChannelPinMixin,
1327
+ ChannelSlowmodeMixin,
1328
+ ThreadChannelMixin,
1329
+ AppliedTagsMixin
1330
+ ]);
1331
+
1332
+ // src/channels/StageChannel.ts
1333
+ var StageChannel = class extends Channel {
1334
+ static {
1335
+ __name(this, "StageChannel");
1336
+ }
1337
+ constructor(data) {
1338
+ super(data);
1339
+ this.optimizeData(data);
1340
+ }
1341
+ };
1342
+ Mixin(StageChannel, [
1343
+ ChannelParentMixin,
1344
+ ChannelPermissionMixin,
1345
+ ChannelSlowmodeMixin,
1346
+ ChannelWebhookMixin,
1347
+ VoiceChannelMixin
1348
+ ]);
1349
+
1350
+ // src/channels/TextChannel.ts
1351
+ var TextChannel = class extends Channel {
1352
+ static {
1353
+ __name(this, "TextChannel");
1354
+ }
1355
+ constructor(data) {
1356
+ super(data);
1357
+ this.optimizeData(data);
1358
+ }
1359
+ };
1360
+ Mixin(TextChannel, [
1361
+ TextChannelMixin,
1362
+ ChannelParentMixin,
1363
+ ChannelPermissionMixin,
1364
+ ChannelPinMixin,
1365
+ ChannelSlowmodeMixin,
1366
+ ChannelTopicMixin
1367
+ ]);
1368
+
1369
+ // src/channels/VoiceChannel.ts
1370
+ var VoiceChannel = class extends Channel {
1371
+ static {
1372
+ __name(this, "VoiceChannel");
1373
+ }
1374
+ constructor(data) {
1375
+ super(data);
1376
+ this.optimizeData(data);
1377
+ }
1378
+ };
1379
+ Mixin(VoiceChannel, [
1380
+ ChannelParentMixin,
1381
+ ChannelPermissionMixin,
1382
+ ChannelSlowmodeMixin,
1383
+ ChannelWebhookMixin,
1384
+ VoiceChannelMixin
1385
+ ]);
1386
+
1387
+ // src/invites/Invite.ts
1388
+ import { RouteBases } from "discord-api-types/v10";
1389
+ var Invite = class extends Structure {
1390
+ static {
1391
+ __name(this, "Invite");
1392
+ }
1393
+ /**
1394
+ * The template used for removing data from the raw data stored for each Invite
1395
+ *
1396
+ * @remarks This template has defaults, if you want to remove additional data and keep the defaults,
1397
+ * use `Object.defineProperties`. To override the defaults, set this value directly.
1398
+ */
1399
+ static DataTemplate = {
1400
+ set created_at(_) {
1401
+ },
1402
+ set expires_at(_) {
1403
+ }
1404
+ };
1405
+ /**
1406
+ * Optimized storage of {@link discord-api-types/v10#(APIActualInvite:interface).expires_at}
1407
+ *
1408
+ * @internal
1409
+ */
1410
+ [kExpiresTimestamp] = null;
1411
+ /**
1412
+ * Optimized storage of {@link discord-api-types/v10#(APIActualInvite:interface).created_at}
1413
+ *
1414
+ * @internal
1415
+ */
1416
+ [kCreatedTimestamp] = null;
1417
+ /**
1418
+ * @param data - The raw data received from the API for the invite
1419
+ */
1420
+ constructor(data) {
1421
+ super(data);
1422
+ this.optimizeData(data);
1423
+ }
1424
+ /**
1425
+ * {@inheritDoc Structure.[kPatch]}
1426
+ *
1427
+ * @internal
1428
+ */
1429
+ [kPatch](data) {
1430
+ super[kPatch](data);
1431
+ return this;
1432
+ }
1433
+ /**
1434
+ * {@inheritDoc Structure.optimizeData}
1435
+ *
1436
+ * @internal
1437
+ */
1438
+ optimizeData(data) {
1439
+ if (data.expires_at) {
1440
+ this[kExpiresTimestamp] = Date.parse(data.expires_at);
1441
+ }
1442
+ if (data.created_at) {
1443
+ this[kCreatedTimestamp] = Date.parse(data.created_at);
1444
+ }
1445
+ }
1446
+ /**
1447
+ * The code for this invite
1448
+ */
1449
+ get code() {
1450
+ return this[kData].code;
1451
+ }
1452
+ /**
1453
+ * The target type (for voice channel invites)
1454
+ */
1455
+ get targetType() {
1456
+ return this[kData].target_type;
1457
+ }
1458
+ /**
1459
+ * The type of this invite
1460
+ */
1461
+ get type() {
1462
+ return this[kData].type;
1463
+ }
1464
+ /**
1465
+ * The approximate number of online members of the guild this invite is for
1466
+ *
1467
+ * @remarks Only available when the invite was fetched from `GET /invites/<code>` with counts
1468
+ */
1469
+ get approximatePresenceCount() {
1470
+ return this[kData].approximate_presence_count;
1471
+ }
1472
+ /**
1473
+ * The approximate total number of members of the guild this invite is for
1474
+ *
1475
+ * @remarks Only available when the invite was fetched from `GET /invites/<code>` with counts
1476
+ */
1477
+ get approximateMemberCount() {
1478
+ return this[kData].approximate_member_count;
1479
+ }
1480
+ /**
1481
+ * The timestamp this invite will expire at
1482
+ */
1483
+ get expiresTimestamp() {
1484
+ if (this[kExpiresTimestamp]) {
1485
+ return this[kExpiresTimestamp];
1486
+ }
1487
+ const createdTimestamp = this.createdTimestamp;
1488
+ const maxAge = this.maxAge;
1489
+ if (createdTimestamp && maxAge) {
1490
+ this[kExpiresTimestamp] = createdTimestamp + maxAge * 1e3;
1491
+ }
1492
+ return this[kExpiresTimestamp];
1493
+ }
1494
+ /**
1495
+ * The time the invite will expire at
1496
+ */
1497
+ get expiresAt() {
1498
+ const expiresTimestamp = this.expiresTimestamp;
1499
+ return expiresTimestamp ? new Date(expiresTimestamp) : null;
1500
+ }
1501
+ /**
1502
+ * The number of times this invite has been used
1503
+ */
1504
+ get uses() {
1505
+ return this[kData].uses;
1506
+ }
1507
+ /**
1508
+ * The maximum number of times this invite can be used
1509
+ */
1510
+ get maxUses() {
1511
+ return this[kData].max_uses;
1512
+ }
1513
+ /**
1514
+ * The maximum age of the invite, in seconds, 0 for non-expiring
1515
+ */
1516
+ get maxAge() {
1517
+ return this[kData].max_age;
1518
+ }
1519
+ /**
1520
+ * Whether this invite only grants temporary membership
1521
+ */
1522
+ get temporary() {
1523
+ return this[kData].temporary;
1524
+ }
1525
+ /**
1526
+ * The timestamp this invite was created at
1527
+ */
1528
+ get createdTimestamp() {
1529
+ return this[kCreatedTimestamp];
1530
+ }
1531
+ /**
1532
+ * The time the invite was created at
1533
+ */
1534
+ get createdAt() {
1535
+ const createdTimestamp = this.createdTimestamp;
1536
+ return createdTimestamp ? new Date(createdTimestamp) : null;
1537
+ }
1538
+ /**
1539
+ * The URL to the invite
1540
+ */
1541
+ get url() {
1542
+ return this.code ? `${RouteBases.invite}/${this.code}` : null;
1543
+ }
1544
+ /**
1545
+ * When concatenated with a string, this automatically concatenates the invite's URL instead of the object.
1546
+ *
1547
+ * @returns The URL to the invite or an empty string if it doesn't have a code
1548
+ */
1549
+ toString() {
1550
+ return this.url ?? "";
1551
+ }
1552
+ /**
1553
+ * {@inheritDoc Structure.toJSON}
1554
+ */
1555
+ toJSON() {
1556
+ const clone = super.toJSON();
1557
+ if (this[kExpiresTimestamp]) {
1558
+ clone.expires_at = new Date(this[kExpiresTimestamp]).toISOString();
1559
+ }
1560
+ if (this[kCreatedTimestamp]) {
1561
+ clone.created_at = new Date(this[kCreatedTimestamp]).toISOString();
1562
+ }
1563
+ return clone;
1564
+ }
1565
+ /**
1566
+ * Returns the primitive value of the specified object.
1567
+ */
1568
+ valueOf() {
1569
+ return this.code ?? super.valueOf();
1570
+ }
1571
+ };
1572
+
1573
+ // src/users/AvatarDecorationData.ts
1574
+ var AvatarDecorationData = class extends Structure {
1575
+ static {
1576
+ __name(this, "AvatarDecorationData");
1577
+ }
1578
+ /**
1579
+ * The template used for removing data from the raw data stored for each Connection
1580
+ */
1581
+ static DataTemplate = {};
1582
+ /**
1583
+ * @param data - The raw data received from the API for the connection
1584
+ */
1585
+ constructor(data) {
1586
+ super(data);
1587
+ }
1588
+ /**
1589
+ * The id of the SKU this avatar decoration is part of.
1590
+ */
1591
+ get skuId() {
1592
+ return this[kData].sku_id;
1593
+ }
1594
+ /**
1595
+ * The asset of this avatar decoration.
1596
+ */
1597
+ get asset() {
1598
+ return this[kData].asset;
1599
+ }
1600
+ };
1601
+
1602
+ // src/users/User.ts
1603
+ import { DiscordSnowflake as DiscordSnowflake2 } from "@sapphire/snowflake";
1604
+ var User = class extends Structure {
1605
+ static {
1606
+ __name(this, "User");
1607
+ }
1608
+ /**
1609
+ * The template used for removing data from the raw data stored for each User
1610
+ */
1611
+ static DataTemplate = {};
1612
+ /**
1613
+ * @param data - The raw data received from the API for the user
1614
+ */
1615
+ constructor(data) {
1616
+ super(data);
1617
+ }
1618
+ /**
1619
+ * {@inheritDoc Structure.[kPatch]}
1620
+ *
1621
+ * @internal
1622
+ */
1623
+ [kPatch](data) {
1624
+ return super[kPatch](data);
1625
+ }
1626
+ /**
1627
+ * The user's id
1628
+ */
1629
+ get id() {
1630
+ return this[kData].id;
1631
+ }
1632
+ /**
1633
+ * The username of the user
1634
+ */
1635
+ get username() {
1636
+ return this[kData].username;
1637
+ }
1638
+ /**
1639
+ * The user's 4 digit tag, if a bot
1640
+ */
1641
+ get discriminator() {
1642
+ return this[kData].discriminator;
1643
+ }
1644
+ /**
1645
+ * The user's display name, the application name for bots
1646
+ */
1647
+ get globalName() {
1648
+ return this[kData].global_name;
1649
+ }
1650
+ /**
1651
+ * The name displayed in the client for this user when no nickname is set
1652
+ */
1653
+ get displayName() {
1654
+ return this.globalName ?? this.username;
1655
+ }
1656
+ /**
1657
+ * The user avatar's hash
1658
+ */
1659
+ get avatar() {
1660
+ return this[kData].avatar;
1661
+ }
1662
+ /**
1663
+ * Whether the user is a bot
1664
+ */
1665
+ get bot() {
1666
+ return this[kData].bot ?? false;
1667
+ }
1668
+ /**
1669
+ * Whether the user is an Official Discord System user
1670
+ */
1671
+ get system() {
1672
+ return this[kData].system ?? false;
1673
+ }
1674
+ /**
1675
+ * Whether the user has mfa enabled
1676
+ *
1677
+ * @remarks This property is only set when the user was fetched with an OAuth2 token and the `identify` scope
1678
+ */
1679
+ get mfaEnabled() {
1680
+ return this[kData].mfa_enabled;
1681
+ }
1682
+ /**
1683
+ * The user's banner hash
1684
+ *
1685
+ * @remarks This property is only set when the user was manually fetched
1686
+ */
1687
+ get banner() {
1688
+ return this[kData].banner;
1689
+ }
1690
+ /**
1691
+ * The base 10 accent color of the user's banner
1692
+ *
1693
+ * @remarks This property is only set when the user was manually fetched
1694
+ */
1695
+ get accentColor() {
1696
+ return this[kData].accent_color;
1697
+ }
1698
+ /**
1699
+ * The user's primary Discord language
1700
+ *
1701
+ * @remarks This property is only set when the user was fetched with an Oauth2 token and the `identify` scope
1702
+ */
1703
+ get locale() {
1704
+ return this[kData].locale;
1705
+ }
1706
+ /**
1707
+ * Whether the email on the user's account has been verified
1708
+ *
1709
+ * @remarks This property is only set when the user was fetched with an OAuth2 token and the `email` scope
1710
+ */
1711
+ get verified() {
1712
+ return this[kData].verified;
1713
+ }
1714
+ /**
1715
+ * The user's email
1716
+ *
1717
+ * @remarks This property is only set when the user was fetched with an OAuth2 token and the `email` scope
1718
+ */
1719
+ get email() {
1720
+ return this[kData].email;
1721
+ }
1722
+ /**
1723
+ * The type of nitro subscription on the user's account
1724
+ *
1725
+ * @remarks This property is only set when the user was fetched with an OAuth2 token and the `identify` scope
1726
+ */
1727
+ get premiumType() {
1728
+ return this[kData].premium_type;
1729
+ }
1730
+ /**
1731
+ * The timestamp the user was created at
1732
+ */
1733
+ get createdTimestamp() {
1734
+ return isIdSet(this.id) ? DiscordSnowflake2.timestampFrom(this.id) : null;
1735
+ }
1736
+ /**
1737
+ * The time the user was created at
1738
+ */
1739
+ get createdAt() {
1740
+ const createdTimestamp = this.createdTimestamp;
1741
+ return createdTimestamp ? new Date(createdTimestamp) : null;
1742
+ }
1743
+ /**
1744
+ * The hexadecimal version of the user accent color, with a leading hash
1745
+ *
1746
+ * @remarks This property is only set when the user was manually fetched
1747
+ */
1748
+ get hexAccentColor() {
1749
+ const accentColor = this.accentColor;
1750
+ if (typeof accentColor !== "number") return accentColor;
1751
+ return `#${accentColor.toString(16).padStart(6, "0")}`;
1752
+ }
1753
+ };
1754
+
1755
+ // src/users/Connection.ts
1756
+ var Connection = class extends Structure {
1757
+ static {
1758
+ __name(this, "Connection");
1759
+ }
1760
+ /**
1761
+ * The template used for removing data from the raw data stored for each Connection
1762
+ */
1763
+ static DataTemplate = {};
1764
+ /**
1765
+ * @param data - The raw data received from the API for the connection
1766
+ */
1767
+ constructor(data) {
1768
+ super(data);
1769
+ }
1770
+ /**
1771
+ * {@inheritDoc Structure.[kPatch]}
1772
+ *
1773
+ * @internal
1774
+ */
1775
+ [kPatch](data) {
1776
+ return super[kPatch](data);
1777
+ }
1778
+ /**
1779
+ * The id of the connection account
1780
+ */
1781
+ get id() {
1782
+ return this[kData].id;
1783
+ }
1784
+ /**
1785
+ * The username of the connection account
1786
+ */
1787
+ get name() {
1788
+ return this[kData].name;
1789
+ }
1790
+ /**
1791
+ * The type of service this connection is for
1792
+ */
1793
+ get type() {
1794
+ return this[kData].type;
1795
+ }
1796
+ /**
1797
+ * Whether the connection is revoked
1798
+ */
1799
+ get revoked() {
1800
+ return this[kData].revoked ?? false;
1801
+ }
1802
+ /**
1803
+ * Whether the connection is verified
1804
+ */
1805
+ get verified() {
1806
+ return this[kData].verified;
1807
+ }
1808
+ /**
1809
+ * Whether friend sync is enabled for this connection
1810
+ */
1811
+ get friendSync() {
1812
+ return this[kData].friend_sync;
1813
+ }
1814
+ /**
1815
+ * Whether activities related to this connection are shown in the users presence
1816
+ */
1817
+ get showActivity() {
1818
+ return this[kData].show_activity;
1819
+ }
1820
+ /**
1821
+ * Whether this connection has an Oauth2 token for console voice transfer
1822
+ */
1823
+ get twoWayLink() {
1824
+ return this[kData].two_way_link;
1825
+ }
1826
+ /**
1827
+ * The visibility state for this connection
1828
+ */
1829
+ get visibility() {
1830
+ return this[kData].visibility;
1831
+ }
1832
+ };
1833
+
1834
+ // src/utils/optimization.ts
1835
+ function extendTemplate(superTemplate, additions) {
1836
+ return Object.defineProperties(additions, Object.getOwnPropertyDescriptors(superTemplate));
1837
+ }
1838
+ __name(extendTemplate, "extendTemplate");
1839
+ export {
1840
+ AnnouncementChannel,
1841
+ AnnouncementThreadChannel,
1842
+ AppliedTagsMixin,
1843
+ AvatarDecorationData,
1844
+ BitField,
1845
+ CategoryChannel,
1846
+ Channel,
1847
+ ChannelFlagsBitField,
1848
+ ChannelOwnerMixin,
1849
+ ChannelParentMixin,
1850
+ ChannelPermissionMixin,
1851
+ ChannelPinMixin,
1852
+ ChannelSlowmodeMixin,
1853
+ ChannelTopicMixin,
1854
+ ChannelWebhookMixin,
1855
+ Connection,
1856
+ DMChannel,
1857
+ DMChannelMixin,
1858
+ DataTemplatePropertyName,
1859
+ ForumChannel,
1860
+ ForumTag,
1861
+ GroupDMChannel,
1862
+ GroupDMMixin,
1863
+ GuildChannelMixin,
1864
+ Invite,
1865
+ MediaChannel,
1866
+ Mixin,
1867
+ OptimizeDataPropertyName,
1868
+ PermissionOverwrite,
1869
+ PermissionsBitField,
1870
+ PrivateThreadChannel,
1871
+ PublicThreadChannel,
1872
+ StageChannel,
1873
+ Structure,
1874
+ TextChannel,
1875
+ TextChannelMixin,
1876
+ ThreadChannelMixin,
1877
+ ThreadMetadata,
1878
+ ThreadOnlyChannelMixin,
1879
+ User,
1880
+ VoiceChannel,
1881
+ VoiceChannelMixin,
1882
+ extendTemplate
1883
+ };
1884
+ //# sourceMappingURL=index.mjs.map