lunibee 0.1.8 → 0.2.1
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/README.md +2 -0
- package/dist/builders/components.d.ts +30 -2
- package/dist/builders/embed.d.ts +7 -7
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +110 -18
- package/dist/builders/index.js.map +6 -6
- package/dist/collection/index.d.ts +68 -1
- package/dist/collection/index.js +334 -1
- package/dist/collection/index.js.map +3 -3
- package/dist/core/collector.d.ts +13 -0
- package/dist/core/events.d.ts +29 -3
- package/dist/core/index.d.ts +25 -9
- package/dist/core/index.js +1745 -134
- package/dist/core/index.js.map +30 -26
- package/dist/core/permissions.d.ts +48 -0
- package/dist/index.js +2102 -362
- package/dist/index.js.map +36 -34
- package/dist/managers/advanced.d.ts +116 -0
- package/dist/managers/base.d.ts +13 -2
- package/dist/managers/emoji.d.ts +1 -1
- package/dist/managers/guild-resources.d.ts +22 -2
- package/dist/managers/guild.d.ts +31 -3
- package/dist/managers/index.d.ts +38 -6
- package/dist/managers/index.js +996 -160
- package/dist/managers/index.js.map +20 -18
- package/dist/managers/member.d.ts +13 -12
- package/dist/managers/message.d.ts +21 -4
- package/dist/rest/errors.d.ts +33 -0
- package/dist/rest/index.d.ts +1 -1
- package/dist/rest/index.js +52 -6
- package/dist/rest/index.js.map +5 -5
- package/dist/rest/routes.d.ts +20 -0
- package/dist/sharding/index.d.ts +29 -0
- package/dist/sharding/index.js +99 -15
- package/dist/sharding/index.js.map +8 -8
- package/dist/structures/base.d.ts +38 -0
- package/dist/structures/index.d.ts +29 -0
- package/dist/structures/index.js +208 -46
- package/dist/structures/index.js.map +13 -12
- package/dist/structures/interactions.d.ts +51 -1
- package/dist/structures/options.d.ts +2 -0
- package/dist/structures/resources.d.ts +29 -3
- package/dist/types/gateway.d.ts +16 -0
- package/dist/types/index.d.ts +67 -1
- package/dist/types/index.js.map +3 -3
- package/dist/utils/args.d.ts +79 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +190 -2
- package/dist/utils/index.js.map +5 -4
- package/dist/voice/index.d.ts +3 -0
- package/dist/voice/index.js +15 -1
- package/dist/voice/index.js.map +3 -3
- package/dist/ws/index.js +13 -5
- package/dist/ws/index.js.map +6 -6
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -53,8 +53,11 @@ var Permission = {
|
|
|
53
53
|
createEvents: 1n << 44n,
|
|
54
54
|
useExternalSounds: 1n << 45n,
|
|
55
55
|
sendVoiceMessages: 1n << 46n,
|
|
56
|
+
setVoiceChannelStatus: 1n << 48n,
|
|
56
57
|
sendPolls: 1n << 49n,
|
|
57
|
-
useExternalApps: 1n << 50n
|
|
58
|
+
useExternalApps: 1n << 50n,
|
|
59
|
+
pinMessages: 1n << 51n,
|
|
60
|
+
bypassSlowmode: 1n << 52n
|
|
58
61
|
};
|
|
59
62
|
var Permissions = {
|
|
60
63
|
CreateInstantInvite: 1n << 0n,
|
|
@@ -104,8 +107,11 @@ var Permissions = {
|
|
|
104
107
|
CreateEvents: 1n << 44n,
|
|
105
108
|
UseExternalSounds: 1n << 45n,
|
|
106
109
|
SendVoiceMessages: 1n << 46n,
|
|
110
|
+
SetVoiceChannelStatus: 1n << 48n,
|
|
107
111
|
SendPolls: 1n << 49n,
|
|
108
|
-
UseExternalApps: 1n << 50n
|
|
112
|
+
UseExternalApps: 1n << 50n,
|
|
113
|
+
PinMessages: 1n << 51n,
|
|
114
|
+
BypassSlowmode: 1n << 52n
|
|
109
115
|
};
|
|
110
116
|
var PermissionFlagsBits = {
|
|
111
117
|
CreateInstantInvite: 1n << 0n,
|
|
@@ -155,8 +161,11 @@ var PermissionFlagsBits = {
|
|
|
155
161
|
CreateEvents: 1n << 44n,
|
|
156
162
|
UseExternalSounds: 1n << 45n,
|
|
157
163
|
SendVoiceMessages: 1n << 46n,
|
|
164
|
+
SetVoiceChannelStatus: 1n << 48n,
|
|
158
165
|
SendPolls: 1n << 49n,
|
|
159
|
-
UseExternalApps: 1n << 50n
|
|
166
|
+
UseExternalApps: 1n << 50n,
|
|
167
|
+
PinMessages: 1n << 51n,
|
|
168
|
+
BypassSlowmode: 1n << 52n
|
|
160
169
|
};
|
|
161
170
|
|
|
162
171
|
class PermissionSet {
|
|
@@ -358,6 +367,10 @@ class PermissionSet {
|
|
|
358
367
|
}
|
|
359
368
|
return false;
|
|
360
369
|
}
|
|
370
|
+
missing(...permissions) {
|
|
371
|
+
const wanted = new PermissionSet(permissions);
|
|
372
|
+
return wanted.toArray().filter((name) => !this.has(name));
|
|
373
|
+
}
|
|
361
374
|
add(...permissions) {
|
|
362
375
|
let bitfield = this.bitfield;
|
|
363
376
|
for (let i = 0;i < permissions.length; i++) {
|
|
@@ -383,6 +396,11 @@ class PermissionSet {
|
|
|
383
396
|
toArray() {
|
|
384
397
|
return Object.keys(Permission).filter((permission) => this.has(permission));
|
|
385
398
|
}
|
|
399
|
+
static #renamed = {
|
|
400
|
+
ManageEmojisAndStickers: "ManageGuildExpressions",
|
|
401
|
+
ManageEmojis: "ManageGuildExpressions",
|
|
402
|
+
UseSlashCommands: "UseApplicationCommands"
|
|
403
|
+
};
|
|
386
404
|
#resolve(permission) {
|
|
387
405
|
if (typeof permission === "bigint")
|
|
388
406
|
return permission;
|
|
@@ -397,6 +415,9 @@ class PermissionSet {
|
|
|
397
415
|
return bit;
|
|
398
416
|
}
|
|
399
417
|
if (typeof permission === "string") {
|
|
418
|
+
const renamed = PermissionSet.#renamed[permission];
|
|
419
|
+
if (renamed)
|
|
420
|
+
return this.#resolve(renamed);
|
|
400
421
|
if (permission in Permission)
|
|
401
422
|
return Permission[permission];
|
|
402
423
|
if (permission in Permissions)
|
|
@@ -419,6 +440,35 @@ class PermissionsBitField extends PermissionSet {
|
|
|
419
440
|
super(value);
|
|
420
441
|
}
|
|
421
442
|
}
|
|
443
|
+
var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
|
|
444
|
+
var bits = (value) => new PermissionSet(value).bitfield;
|
|
445
|
+
function computePermissions(context) {
|
|
446
|
+
if (context.ownerId !== undefined && context.ownerId === context.memberId)
|
|
447
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
448
|
+
const roles = new Map(context.roles.map((role) => [role.id, role]));
|
|
449
|
+
let base = bits(roles.get(context.guildId)?.permissions ?? 0n);
|
|
450
|
+
for (const id of context.memberRoleIds)
|
|
451
|
+
base |= bits(roles.get(id)?.permissions ?? 0n);
|
|
452
|
+
if (base & Permission.administrator)
|
|
453
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
454
|
+
const overwrites = context.overwrites ?? [];
|
|
455
|
+
const everyone = overwrites.find((o) => o.id === context.guildId);
|
|
456
|
+
if (everyone)
|
|
457
|
+
base = base & ~bits(everyone.deny) | bits(everyone.allow);
|
|
458
|
+
const memberRoles = new Set(context.memberRoleIds);
|
|
459
|
+
let allow = 0n;
|
|
460
|
+
let deny = 0n;
|
|
461
|
+
for (const overwrite of overwrites)
|
|
462
|
+
if (overwrite.type === 0 /* Role */ && overwrite.id !== context.guildId && memberRoles.has(overwrite.id)) {
|
|
463
|
+
allow |= bits(overwrite.allow);
|
|
464
|
+
deny |= bits(overwrite.deny);
|
|
465
|
+
}
|
|
466
|
+
base = base & ~deny | allow;
|
|
467
|
+
const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
|
|
468
|
+
if (member)
|
|
469
|
+
base = base & ~bits(member.deny) | bits(member.allow);
|
|
470
|
+
return new PermissionSet(base);
|
|
471
|
+
}
|
|
422
472
|
// packages/core/src/events.ts
|
|
423
473
|
var ClientEvent;
|
|
424
474
|
((ClientEvent) => {
|
|
@@ -455,6 +505,13 @@ var ClientEvent;
|
|
|
455
505
|
ClientEvent["GuildRoleDelete"] = "guildRoleDelete";
|
|
456
506
|
ClientEvent["GuildEmojisUpdate"] = "guildEmojisUpdate";
|
|
457
507
|
ClientEvent["GuildStickersUpdate"] = "guildStickersUpdate";
|
|
508
|
+
ClientEvent["EntitlementCreate"] = "entitlementCreate";
|
|
509
|
+
ClientEvent["EntitlementUpdate"] = "entitlementUpdate";
|
|
510
|
+
ClientEvent["EntitlementDelete"] = "entitlementDelete";
|
|
511
|
+
ClientEvent["SoundboardSoundCreate"] = "soundboardSoundCreate";
|
|
512
|
+
ClientEvent["SoundboardSoundUpdate"] = "soundboardSoundUpdate";
|
|
513
|
+
ClientEvent["SoundboardSoundDelete"] = "soundboardSoundDelete";
|
|
514
|
+
ClientEvent["SoundboardSoundsUpdate"] = "soundboardSoundsUpdate";
|
|
458
515
|
ClientEvent["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
|
|
459
516
|
ClientEvent["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
|
|
460
517
|
ClientEvent["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
|
|
@@ -497,6 +554,9 @@ class Collector extends EventEmitter {
|
|
|
497
554
|
endReason;
|
|
498
555
|
totalProcessed = 0;
|
|
499
556
|
#timeoutTimer;
|
|
557
|
+
#idleTimer;
|
|
558
|
+
#onAbort = () => this.stop("abort");
|
|
559
|
+
#cleanup = [];
|
|
500
560
|
constructor(options = {}) {
|
|
501
561
|
super();
|
|
502
562
|
this.options = options;
|
|
@@ -505,6 +565,27 @@ class Collector extends EventEmitter {
|
|
|
505
565
|
this.stop("time");
|
|
506
566
|
}, options.time);
|
|
507
567
|
}
|
|
568
|
+
this.#resetIdle();
|
|
569
|
+
if (options.signal?.aborted)
|
|
570
|
+
this.stop("abort");
|
|
571
|
+
else
|
|
572
|
+
options.signal?.addEventListener("abort", this.#onAbort, {
|
|
573
|
+
once: true
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
onDispose(cleanup) {
|
|
577
|
+
if (this.ended)
|
|
578
|
+
cleanup();
|
|
579
|
+
else
|
|
580
|
+
this.#cleanup.push(cleanup);
|
|
581
|
+
return this;
|
|
582
|
+
}
|
|
583
|
+
#resetIdle() {
|
|
584
|
+
if (!this.options.idle || this.options.idle <= 0)
|
|
585
|
+
return;
|
|
586
|
+
if (this.#idleTimer)
|
|
587
|
+
clearTimeout(this.#idleTimer);
|
|
588
|
+
this.#idleTimer = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
508
589
|
}
|
|
509
590
|
async handle(key, item) {
|
|
510
591
|
if (this.ended)
|
|
@@ -522,6 +603,7 @@ class Collector extends EventEmitter {
|
|
|
522
603
|
return false;
|
|
523
604
|
}
|
|
524
605
|
this.collected.set(key, item);
|
|
606
|
+
this.#resetIdle();
|
|
525
607
|
this.emit("collect", item);
|
|
526
608
|
if (this.options.max && this.collected.size >= this.options.max) {
|
|
527
609
|
this.stop("limit");
|
|
@@ -540,9 +622,53 @@ class Collector extends EventEmitter {
|
|
|
540
622
|
this.endReason = reason;
|
|
541
623
|
if (this.#timeoutTimer)
|
|
542
624
|
clearTimeout(this.#timeoutTimer);
|
|
625
|
+
if (this.#idleTimer)
|
|
626
|
+
clearTimeout(this.#idleTimer);
|
|
627
|
+
this.options.signal?.removeEventListener("abort", this.#onAbort);
|
|
628
|
+
for (const cleanup of this.#cleanup.splice(0)) {
|
|
629
|
+
try {
|
|
630
|
+
cleanup();
|
|
631
|
+
} catch {}
|
|
632
|
+
}
|
|
543
633
|
this.emit("end", this.collected, reason);
|
|
544
634
|
this.removeAllListeners();
|
|
545
635
|
}
|
|
636
|
+
wait() {
|
|
637
|
+
if (this.ended)
|
|
638
|
+
return Promise.resolve(this.collected);
|
|
639
|
+
return new Promise((resolve) => this.once("end", (collected) => resolve(collected)));
|
|
640
|
+
}
|
|
641
|
+
async* [Symbol.asyncIterator]() {
|
|
642
|
+
const queue = [];
|
|
643
|
+
let wake;
|
|
644
|
+
const onCollect = (item) => {
|
|
645
|
+
queue.push(item);
|
|
646
|
+
wake?.();
|
|
647
|
+
};
|
|
648
|
+
const onEnd = () => wake?.();
|
|
649
|
+
if (!this.ended) {
|
|
650
|
+
this.on("collect", onCollect);
|
|
651
|
+
this.on("end", onEnd);
|
|
652
|
+
}
|
|
653
|
+
try {
|
|
654
|
+
for (;; ) {
|
|
655
|
+
if (queue.length > 0) {
|
|
656
|
+
yield queue.shift();
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
if (this.ended)
|
|
660
|
+
return;
|
|
661
|
+
await new Promise((resolve) => wake = resolve);
|
|
662
|
+
wake = undefined;
|
|
663
|
+
}
|
|
664
|
+
} finally {
|
|
665
|
+
this.off("collect", onCollect);
|
|
666
|
+
this.off("end", onEnd);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
[Symbol.dispose]() {
|
|
670
|
+
this.stop("disposed");
|
|
671
|
+
}
|
|
546
672
|
next() {
|
|
547
673
|
return new Promise((resolve, reject) => {
|
|
548
674
|
if (this.ended) {
|
|
@@ -858,7 +984,340 @@ class Cache {
|
|
|
858
984
|
}
|
|
859
985
|
|
|
860
986
|
// packages/collection/src/index.ts
|
|
987
|
+
class RecencyList {
|
|
988
|
+
#nodes = new Map;
|
|
989
|
+
#oldest;
|
|
990
|
+
#newest;
|
|
991
|
+
get size() {
|
|
992
|
+
return this.#nodes.size;
|
|
993
|
+
}
|
|
994
|
+
oldest() {
|
|
995
|
+
return this.#oldest?.key;
|
|
996
|
+
}
|
|
997
|
+
touch(key) {
|
|
998
|
+
const node = this.#nodes.get(key);
|
|
999
|
+
if (node)
|
|
1000
|
+
return this.#moveNewest(node);
|
|
1001
|
+
const created = { key, older: this.#newest };
|
|
1002
|
+
if (this.#newest)
|
|
1003
|
+
this.#newest.newer = created;
|
|
1004
|
+
else
|
|
1005
|
+
this.#oldest = created;
|
|
1006
|
+
this.#newest = created;
|
|
1007
|
+
this.#nodes.set(key, created);
|
|
1008
|
+
}
|
|
1009
|
+
promote(key) {
|
|
1010
|
+
const node = this.#nodes.get(key);
|
|
1011
|
+
if (node)
|
|
1012
|
+
this.#moveNewest(node);
|
|
1013
|
+
}
|
|
1014
|
+
delete(key) {
|
|
1015
|
+
const node = this.#nodes.get(key);
|
|
1016
|
+
if (!node)
|
|
1017
|
+
return false;
|
|
1018
|
+
this.#unlink(node);
|
|
1019
|
+
this.#nodes.delete(key);
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
clear() {
|
|
1023
|
+
this.#nodes.clear();
|
|
1024
|
+
this.#oldest = this.#newest = undefined;
|
|
1025
|
+
}
|
|
1026
|
+
#unlink(node) {
|
|
1027
|
+
if (node.older)
|
|
1028
|
+
node.older.newer = node.newer;
|
|
1029
|
+
else
|
|
1030
|
+
this.#oldest = node.newer;
|
|
1031
|
+
if (node.newer)
|
|
1032
|
+
node.newer.older = node.older;
|
|
1033
|
+
else
|
|
1034
|
+
this.#newest = node.older;
|
|
1035
|
+
node.older = node.newer = undefined;
|
|
1036
|
+
}
|
|
1037
|
+
#moveNewest(node) {
|
|
1038
|
+
if (node === this.#newest)
|
|
1039
|
+
return;
|
|
1040
|
+
this.#unlink(node);
|
|
1041
|
+
node.older = this.#newest;
|
|
1042
|
+
if (this.#newest)
|
|
1043
|
+
this.#newest.newer = node;
|
|
1044
|
+
else
|
|
1045
|
+
this.#oldest = node;
|
|
1046
|
+
this.#newest = node;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
function assertTTL(ttl) {
|
|
1050
|
+
if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
|
|
1051
|
+
throw new RangeError("TTL must be a positive number, or omitted.");
|
|
1052
|
+
}
|
|
1053
|
+
|
|
861
1054
|
class Collection extends Map {
|
|
1055
|
+
#ttl;
|
|
1056
|
+
#maxSize;
|
|
1057
|
+
#onEvict;
|
|
1058
|
+
#expiry = new Map;
|
|
1059
|
+
#lru = new RecencyList;
|
|
1060
|
+
#stats = {
|
|
1061
|
+
hits: 0,
|
|
1062
|
+
misses: 0,
|
|
1063
|
+
expired: 0,
|
|
1064
|
+
evicted: 0
|
|
1065
|
+
};
|
|
1066
|
+
#heap = [];
|
|
1067
|
+
#timer;
|
|
1068
|
+
#armedFor = Infinity;
|
|
1069
|
+
constructor(entries, options = {}) {
|
|
1070
|
+
super();
|
|
1071
|
+
assertTTL(options.ttl);
|
|
1072
|
+
if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
|
|
1073
|
+
throw new RangeError("maxSize must be a positive integer.");
|
|
1074
|
+
this.#ttl = options.ttl;
|
|
1075
|
+
this.#maxSize = options.maxSize;
|
|
1076
|
+
this.#onEvict = options.onEvict;
|
|
1077
|
+
if (entries)
|
|
1078
|
+
for (const [key, value] of entries)
|
|
1079
|
+
this.set(key, value);
|
|
1080
|
+
}
|
|
1081
|
+
set(key, value, ttl) {
|
|
1082
|
+
assertTTL(ttl);
|
|
1083
|
+
const window = ttl ?? this.#ttl;
|
|
1084
|
+
if (this.#maxSize !== undefined) {
|
|
1085
|
+
this.#lru.touch(key);
|
|
1086
|
+
}
|
|
1087
|
+
super.set(key, value);
|
|
1088
|
+
if (window !== undefined)
|
|
1089
|
+
this.#schedule(key, window);
|
|
1090
|
+
else if (this.#expiry.size > 0)
|
|
1091
|
+
this.#expiry.delete(key);
|
|
1092
|
+
this.#enforceCap();
|
|
1093
|
+
return this;
|
|
1094
|
+
}
|
|
1095
|
+
setWithoutTTL(key, value) {
|
|
1096
|
+
if (this.#expiry.size > 0)
|
|
1097
|
+
this.#expiry.delete(key);
|
|
1098
|
+
if (this.#lru.size > 0)
|
|
1099
|
+
this.#lru.delete(key);
|
|
1100
|
+
super.set(key, value);
|
|
1101
|
+
return this;
|
|
1102
|
+
}
|
|
1103
|
+
get(key) {
|
|
1104
|
+
if (this.#expireIfDue(key)) {
|
|
1105
|
+
this.#stats.misses++;
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const value = super.get(key);
|
|
1109
|
+
if (value === undefined && !super.has(key)) {
|
|
1110
|
+
this.#stats.misses++;
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
this.#stats.hits++;
|
|
1114
|
+
const expiry = this.#expiry.get(key);
|
|
1115
|
+
if (expiry)
|
|
1116
|
+
expiry.deadline = Date.now() + expiry.window;
|
|
1117
|
+
this.#lru.promote(key);
|
|
1118
|
+
return value;
|
|
1119
|
+
}
|
|
1120
|
+
peek(key) {
|
|
1121
|
+
if (!this.#expireIfDue(key) && super.has(key)) {
|
|
1122
|
+
this.#stats.hits++;
|
|
1123
|
+
return super.get(key);
|
|
1124
|
+
}
|
|
1125
|
+
this.#stats.misses++;
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
get stats() {
|
|
1129
|
+
return { ...this.#stats };
|
|
1130
|
+
}
|
|
1131
|
+
has(key) {
|
|
1132
|
+
return !this.#expireIfDue(key) && super.has(key);
|
|
1133
|
+
}
|
|
1134
|
+
delete(key) {
|
|
1135
|
+
if (this.#expireIfDue(key))
|
|
1136
|
+
return false;
|
|
1137
|
+
this.#expiry.delete(key);
|
|
1138
|
+
this.#lru.delete(key);
|
|
1139
|
+
return super.delete(key);
|
|
1140
|
+
}
|
|
1141
|
+
clear() {
|
|
1142
|
+
super.clear();
|
|
1143
|
+
this.#expiry.clear();
|
|
1144
|
+
this.#lru.clear();
|
|
1145
|
+
this.#heap.length = 0;
|
|
1146
|
+
if (this.#timer)
|
|
1147
|
+
clearTimeout(this.#timer);
|
|
1148
|
+
this.#timer = undefined;
|
|
1149
|
+
this.#armedFor = Infinity;
|
|
1150
|
+
}
|
|
1151
|
+
get size() {
|
|
1152
|
+
this.purge();
|
|
1153
|
+
return super.size;
|
|
1154
|
+
}
|
|
1155
|
+
entries() {
|
|
1156
|
+
this.purge();
|
|
1157
|
+
return super.entries();
|
|
1158
|
+
}
|
|
1159
|
+
keys() {
|
|
1160
|
+
this.purge();
|
|
1161
|
+
return super.keys();
|
|
1162
|
+
}
|
|
1163
|
+
values() {
|
|
1164
|
+
this.purge();
|
|
1165
|
+
return super.values();
|
|
1166
|
+
}
|
|
1167
|
+
[Symbol.iterator]() {
|
|
1168
|
+
return this.entries();
|
|
1169
|
+
}
|
|
1170
|
+
forEach(callback, thisArg) {
|
|
1171
|
+
this.purge();
|
|
1172
|
+
super.forEach(callback, thisArg);
|
|
1173
|
+
}
|
|
1174
|
+
ttlRemaining(key) {
|
|
1175
|
+
if (this.#expireIfDue(key))
|
|
1176
|
+
return;
|
|
1177
|
+
const expiry = this.#expiry.get(key);
|
|
1178
|
+
return expiry && Math.max(0, expiry.deadline - Date.now());
|
|
1179
|
+
}
|
|
1180
|
+
purge() {
|
|
1181
|
+
if (this.#expiry.size === 0)
|
|
1182
|
+
return 0;
|
|
1183
|
+
const now = Date.now();
|
|
1184
|
+
let removed = 0;
|
|
1185
|
+
const dropped = [];
|
|
1186
|
+
while (this.#nextDeadline() <= now) {
|
|
1187
|
+
const due = this.#heapPop();
|
|
1188
|
+
dropped.push([due.key, super.get(due.key)]);
|
|
1189
|
+
this.#remove(due.key);
|
|
1190
|
+
removed++;
|
|
1191
|
+
}
|
|
1192
|
+
this.#stats.expired += removed;
|
|
1193
|
+
this.#rearm();
|
|
1194
|
+
for (const [key, value] of dropped)
|
|
1195
|
+
this.#notify(key, value, "expired");
|
|
1196
|
+
return removed;
|
|
1197
|
+
}
|
|
1198
|
+
#expireIfDue(key) {
|
|
1199
|
+
const expiry = this.#expiry.get(key);
|
|
1200
|
+
if (!expiry || expiry.deadline > Date.now())
|
|
1201
|
+
return false;
|
|
1202
|
+
const value = super.get(key);
|
|
1203
|
+
this.#remove(key);
|
|
1204
|
+
this.#stats.expired++;
|
|
1205
|
+
this.#notify(key, value, "expired");
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
#remove(key) {
|
|
1209
|
+
this.#expiry.delete(key);
|
|
1210
|
+
this.#lru.delete(key);
|
|
1211
|
+
super.delete(key);
|
|
1212
|
+
}
|
|
1213
|
+
#notify(key, value, reason) {
|
|
1214
|
+
if (!this.#onEvict)
|
|
1215
|
+
return;
|
|
1216
|
+
try {
|
|
1217
|
+
this.#onEvict(key, value, reason);
|
|
1218
|
+
} catch {}
|
|
1219
|
+
}
|
|
1220
|
+
#enforceCap() {
|
|
1221
|
+
if (this.#maxSize === undefined)
|
|
1222
|
+
return;
|
|
1223
|
+
while (this.#lru.size > this.#maxSize) {
|
|
1224
|
+
const oldest = this.#lru.oldest();
|
|
1225
|
+
const value = super.get(oldest);
|
|
1226
|
+
this.#remove(oldest);
|
|
1227
|
+
this.#stats.evicted++;
|
|
1228
|
+
this.#notify(oldest, value, "evicted");
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
#schedule(key, window) {
|
|
1232
|
+
const deadline = Date.now() + window;
|
|
1233
|
+
const expiry = this.#expiry.get(key);
|
|
1234
|
+
if (expiry) {
|
|
1235
|
+
expiry.deadline = deadline;
|
|
1236
|
+
expiry.window = window;
|
|
1237
|
+
if (deadline >= expiry.filed)
|
|
1238
|
+
return;
|
|
1239
|
+
expiry.filed = deadline;
|
|
1240
|
+
} else
|
|
1241
|
+
this.#expiry.set(key, { deadline, window, filed: deadline });
|
|
1242
|
+
this.#heapPush({ key, deadline });
|
|
1243
|
+
if (this.#heap.length > 2 * this.#expiry.size + 8)
|
|
1244
|
+
this.#compact();
|
|
1245
|
+
this.#rearm();
|
|
1246
|
+
}
|
|
1247
|
+
#nextDeadline() {
|
|
1248
|
+
for (;; ) {
|
|
1249
|
+
const top = this.#heap[0];
|
|
1250
|
+
if (top === undefined)
|
|
1251
|
+
return Infinity;
|
|
1252
|
+
const expiry = this.#expiry.get(top.key);
|
|
1253
|
+
if (!expiry || expiry.filed !== top.deadline) {
|
|
1254
|
+
this.#heapPop();
|
|
1255
|
+
continue;
|
|
1256
|
+
}
|
|
1257
|
+
if (expiry.deadline === top.deadline)
|
|
1258
|
+
return top.deadline;
|
|
1259
|
+
this.#heapPop();
|
|
1260
|
+
expiry.filed = expiry.deadline;
|
|
1261
|
+
this.#heapPush({ key: top.key, deadline: expiry.deadline });
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
#compact() {
|
|
1265
|
+
const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
|
|
1266
|
+
this.#heap.length = 0;
|
|
1267
|
+
for (const record of live)
|
|
1268
|
+
this.#heapPush(record);
|
|
1269
|
+
}
|
|
1270
|
+
#rearm() {
|
|
1271
|
+
const deadline = this.#nextDeadline();
|
|
1272
|
+
if (this.#timer !== undefined && deadline >= this.#armedFor)
|
|
1273
|
+
return;
|
|
1274
|
+
if (this.#timer)
|
|
1275
|
+
clearTimeout(this.#timer);
|
|
1276
|
+
this.#timer = undefined;
|
|
1277
|
+
this.#armedFor = deadline;
|
|
1278
|
+
if (deadline === Infinity)
|
|
1279
|
+
return;
|
|
1280
|
+
this.#timer = setTimeout(() => {
|
|
1281
|
+
this.#timer = undefined;
|
|
1282
|
+
this.#armedFor = Infinity;
|
|
1283
|
+
this.purge();
|
|
1284
|
+
}, Math.max(0, deadline - Date.now()));
|
|
1285
|
+
this.#timer.unref?.();
|
|
1286
|
+
}
|
|
1287
|
+
#heapPush(record) {
|
|
1288
|
+
const heap = this.#heap;
|
|
1289
|
+
heap.push(record);
|
|
1290
|
+
let i = heap.length - 1;
|
|
1291
|
+
while (i > 0) {
|
|
1292
|
+
const parent = i - 1 >> 1;
|
|
1293
|
+
if (heap[parent].deadline <= heap[i].deadline)
|
|
1294
|
+
break;
|
|
1295
|
+
[heap[parent], heap[i]] = [heap[i], heap[parent]];
|
|
1296
|
+
i = parent;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
#heapPop() {
|
|
1300
|
+
const heap = this.#heap;
|
|
1301
|
+
const top = heap[0];
|
|
1302
|
+
const last = heap.pop();
|
|
1303
|
+
if (top === undefined || heap.length === 0)
|
|
1304
|
+
return top;
|
|
1305
|
+
heap[0] = last;
|
|
1306
|
+
for (let i = 0;; ) {
|
|
1307
|
+
const left = 2 * i + 1;
|
|
1308
|
+
const right = left + 1;
|
|
1309
|
+
let smallest = i;
|
|
1310
|
+
if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
|
|
1311
|
+
smallest = left;
|
|
1312
|
+
if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
|
|
1313
|
+
smallest = right;
|
|
1314
|
+
if (smallest === i)
|
|
1315
|
+
break;
|
|
1316
|
+
[heap[smallest], heap[i]] = [heap[i], heap[smallest]];
|
|
1317
|
+
i = smallest;
|
|
1318
|
+
}
|
|
1319
|
+
return top;
|
|
1320
|
+
}
|
|
862
1321
|
first() {
|
|
863
1322
|
for (const value of this.values())
|
|
864
1323
|
return value;
|
|
@@ -1083,11 +1542,40 @@ class Manager {
|
|
|
1083
1542
|
has(id) {
|
|
1084
1543
|
return this.cache.has(id);
|
|
1085
1544
|
}
|
|
1545
|
+
#inflight = new Map;
|
|
1546
|
+
fetchOnce(id, load, store = (value) => {
|
|
1547
|
+
this.set(id, value);
|
|
1548
|
+
return value;
|
|
1549
|
+
}) {
|
|
1550
|
+
const pending = this.#inflight.get(id);
|
|
1551
|
+
if (pending)
|
|
1552
|
+
return pending.promise;
|
|
1553
|
+
const entry = {
|
|
1554
|
+
promise: new Promise((resolve) => resolve(load())),
|
|
1555
|
+
dirty: false
|
|
1556
|
+
};
|
|
1557
|
+
this.#inflight.set(id, entry);
|
|
1558
|
+
entry.promise = entry.promise.then((value) => {
|
|
1559
|
+
this.#inflight.delete(id);
|
|
1560
|
+
return entry.dirty ? this.get(id) ?? value : store(value);
|
|
1561
|
+
}, (error) => {
|
|
1562
|
+
this.#inflight.delete(id);
|
|
1563
|
+
throw error;
|
|
1564
|
+
});
|
|
1565
|
+
return entry.promise;
|
|
1566
|
+
}
|
|
1567
|
+
#markDirty(id) {
|
|
1568
|
+
const pending = this.#inflight.get(id);
|
|
1569
|
+
if (pending)
|
|
1570
|
+
pending.dirty = true;
|
|
1571
|
+
}
|
|
1086
1572
|
set(id, value) {
|
|
1087
|
-
this
|
|
1573
|
+
this.#markDirty(id);
|
|
1574
|
+
this.cache.setWithoutTTL(id, value);
|
|
1088
1575
|
return this;
|
|
1089
1576
|
}
|
|
1090
1577
|
delete(id) {
|
|
1578
|
+
this.#markDirty(id);
|
|
1091
1579
|
return this.cache.delete(id);
|
|
1092
1580
|
}
|
|
1093
1581
|
clear() {
|
|
@@ -1123,16 +1611,20 @@ class ResourceManager extends Manager {
|
|
|
1123
1611
|
async resolve(id) {
|
|
1124
1612
|
return this.get(id) ?? this.fetch(id);
|
|
1125
1613
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
this.set(id, resource);
|
|
1129
|
-
return resource;
|
|
1614
|
+
fetch(id) {
|
|
1615
|
+
return this.fetchOnce(id, () => this.#fetcher(id));
|
|
1130
1616
|
}
|
|
1131
1617
|
async fetchMany(ids) {
|
|
1132
1618
|
return Promise.all([...ids].map((id) => this.resolve(id)));
|
|
1133
1619
|
}
|
|
1134
1620
|
upsert(resource) {
|
|
1135
1621
|
const key = this.#key(resource);
|
|
1622
|
+
const existing = this.get(key);
|
|
1623
|
+
if (existing !== undefined && existing !== resource && typeof existing === "object" && existing !== null) {
|
|
1624
|
+
Object.assign(existing, resource);
|
|
1625
|
+
this.set(key, existing);
|
|
1626
|
+
return existing;
|
|
1627
|
+
}
|
|
1136
1628
|
this.set(key, resource);
|
|
1137
1629
|
return resource;
|
|
1138
1630
|
}
|
|
@@ -1143,7 +1635,7 @@ class ResourceManager extends Manager {
|
|
|
1143
1635
|
// packages/rest/package.json
|
|
1144
1636
|
var package_default = {
|
|
1145
1637
|
name: "@lunibee/rest",
|
|
1146
|
-
version: "0.1
|
|
1638
|
+
version: "0.2.1",
|
|
1147
1639
|
type: "module",
|
|
1148
1640
|
module: "./src/index.ts",
|
|
1149
1641
|
types: "./src/index.ts",
|
|
@@ -1203,7 +1695,29 @@ class MemoryRateLimitStore {
|
|
|
1203
1695
|
}
|
|
1204
1696
|
|
|
1205
1697
|
// packages/rest/src/errors.ts
|
|
1698
|
+
function kindFromStatus(status) {
|
|
1699
|
+
if (status === 429)
|
|
1700
|
+
return "rateLimited";
|
|
1701
|
+
if (status === 401)
|
|
1702
|
+
return "authentication";
|
|
1703
|
+
if (status === 403)
|
|
1704
|
+
return "permission";
|
|
1705
|
+
if (status === 404)
|
|
1706
|
+
return "notFound";
|
|
1707
|
+
if (status === 400 || status === 422)
|
|
1708
|
+
return "validation";
|
|
1709
|
+
if (status >= 500)
|
|
1710
|
+
return "server";
|
|
1711
|
+
if (status === 0)
|
|
1712
|
+
return "network";
|
|
1713
|
+
return "client";
|
|
1714
|
+
}
|
|
1715
|
+
function redactPath(path) {
|
|
1716
|
+
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/, "$1:token");
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1206
1719
|
class RESTError extends Error {
|
|
1720
|
+
kind;
|
|
1207
1721
|
status;
|
|
1208
1722
|
code;
|
|
1209
1723
|
errors;
|
|
@@ -1213,14 +1727,18 @@ class RESTError extends Error {
|
|
|
1213
1727
|
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
1214
1728
|
this.name = "RESTError";
|
|
1215
1729
|
this.status = status;
|
|
1730
|
+
this.kind = options.kind ?? kindFromStatus(status);
|
|
1216
1731
|
this.code = code;
|
|
1217
1732
|
this.errors = errors;
|
|
1218
1733
|
this.method = options.method;
|
|
1219
|
-
this.path = options.path;
|
|
1734
|
+
this.path = options.path === undefined ? undefined : redactPath(options.path);
|
|
1735
|
+
}
|
|
1736
|
+
get retryable() {
|
|
1737
|
+
return this.kind === "rateLimited" || this.kind === "server" || this.kind === "network" || this.kind === "timeout";
|
|
1220
1738
|
}
|
|
1221
1739
|
}
|
|
1222
1740
|
function abortError(path, reason) {
|
|
1223
|
-
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason });
|
|
1741
|
+
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason, kind: "aborted" });
|
|
1224
1742
|
}
|
|
1225
1743
|
async function sleep(delay, signal, path) {
|
|
1226
1744
|
if (delay <= 0)
|
|
@@ -1555,8 +2073,23 @@ var Routes = {
|
|
|
1555
2073
|
invite: (code) => `/invites/${encodeURIComponent(code)}`,
|
|
1556
2074
|
guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
|
|
1557
2075
|
guildEmoji: (guildId, emojiId) => emojiId ? `/guilds/${snowflake(guildId, "Guild ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/emojis`,
|
|
1558
|
-
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis
|
|
2076
|
+
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`,
|
|
2077
|
+
pollExpire: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/expire`,
|
|
2078
|
+
pollAnswerVoters: (channelId, messageId, answerId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/answers/${integer(answerId, "Answer ID")}`,
|
|
2079
|
+
guildSticker: (guildId, stickerId) => stickerId ? `/guilds/${snowflake(guildId, "Guild ID")}/stickers/${snowflake(stickerId, "Sticker ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/stickers`,
|
|
2080
|
+
sendSoundboardSound: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/send-soundboard-sound`,
|
|
2081
|
+
soundboardDefaultSounds: () => "/soundboard-default-sounds",
|
|
2082
|
+
guildSoundboardSound: (guildId, soundId) => soundId ? `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds/${snowflake(soundId, "Sound ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds`,
|
|
2083
|
+
applicationSkus: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/skus`,
|
|
2084
|
+
applicationEntitlement: (applicationId, entitlementId) => entitlementId ? `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/entitlements`,
|
|
2085
|
+
consumeEntitlement: (applicationId, entitlementId) => `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}/consume`,
|
|
2086
|
+
skuSubscription: (skuId, subscriptionId) => subscriptionId ? `/skus/${snowflake(skuId, "SKU ID")}/subscriptions/${snowflake(subscriptionId, "Subscription ID")}` : `/skus/${snowflake(skuId, "SKU ID")}/subscriptions`
|
|
1559
2087
|
};
|
|
2088
|
+
function integer(value, field) {
|
|
2089
|
+
if (!Number.isInteger(value) || value < 0)
|
|
2090
|
+
throw new TypeError(`${field} must be a non-negative integer.`);
|
|
2091
|
+
return String(value);
|
|
2092
|
+
}
|
|
1560
2093
|
function snowflake(value, field) {
|
|
1561
2094
|
if (!/^\d{1,20}$/.test(value))
|
|
1562
2095
|
throw new TypeError(`${field} must be a valid Discord snowflake.`);
|
|
@@ -1870,7 +2403,8 @@ class REST {
|
|
|
1870
2403
|
throw new RESTError(failure.message, 0, undefined, undefined, {
|
|
1871
2404
|
method,
|
|
1872
2405
|
path,
|
|
1873
|
-
cause: failure.cause ?? failure
|
|
2406
|
+
cause: failure.cause ?? failure,
|
|
2407
|
+
kind: failure.timedOut ? "timeout" : "network"
|
|
1874
2408
|
});
|
|
1875
2409
|
}
|
|
1876
2410
|
this.#emit(this.#hooks.onResponse, {
|
|
@@ -1969,6 +2503,9 @@ class REST {
|
|
|
1969
2503
|
#emit(hook, ctx) {
|
|
1970
2504
|
if (!hook)
|
|
1971
2505
|
return;
|
|
2506
|
+
const withPath = ctx;
|
|
2507
|
+
if (typeof withPath.path === "string")
|
|
2508
|
+
ctx = { ...ctx, path: redactPath(withPath.path) };
|
|
1972
2509
|
Promise.resolve().then(() => hook(ctx)).catch(() => {});
|
|
1973
2510
|
}
|
|
1974
2511
|
}
|
|
@@ -2045,6 +2582,7 @@ class Channel extends BaseStructure {
|
|
|
2045
2582
|
nsfw;
|
|
2046
2583
|
rateLimitPerUser;
|
|
2047
2584
|
position;
|
|
2585
|
+
permissionOverwrites;
|
|
2048
2586
|
#context;
|
|
2049
2587
|
constructor(data, context) {
|
|
2050
2588
|
super(data.id);
|
|
@@ -2058,6 +2596,7 @@ class Channel extends BaseStructure {
|
|
|
2058
2596
|
this.nsfw = data.nsfw;
|
|
2059
2597
|
this.rateLimitPerUser = data.rate_limit_per_user;
|
|
2060
2598
|
this.position = data.position;
|
|
2599
|
+
this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
|
|
2061
2600
|
this.#context = context;
|
|
2062
2601
|
}
|
|
2063
2602
|
sendMessage(options) {
|
|
@@ -2081,6 +2620,11 @@ class Channel extends BaseStructure {
|
|
|
2081
2620
|
editTopic(topic) {
|
|
2082
2621
|
return this.edit({ topic });
|
|
2083
2622
|
}
|
|
2623
|
+
editPermissionOverwrite(targetId, changes, options) {
|
|
2624
|
+
if (!this.#context?.editPermissionOverwrite)
|
|
2625
|
+
throw new Error("This channel is not attached to a client.");
|
|
2626
|
+
return this.#context.editPermissionOverwrite(this.id, targetId, changes, options);
|
|
2627
|
+
}
|
|
2084
2628
|
editParent(parentId) {
|
|
2085
2629
|
return this.edit({ parent_id: parentId });
|
|
2086
2630
|
}
|
|
@@ -2215,6 +2759,7 @@ class Guild extends BaseStructure {
|
|
|
2215
2759
|
return this.name;
|
|
2216
2760
|
}
|
|
2217
2761
|
}
|
|
2762
|
+
|
|
2218
2763
|
// packages/structures/src/resources.ts
|
|
2219
2764
|
function toDateOrNull(value) {
|
|
2220
2765
|
if (!value)
|
|
@@ -2230,13 +2775,15 @@ class GuildMember {
|
|
|
2230
2775
|
roleIds;
|
|
2231
2776
|
pending;
|
|
2232
2777
|
joinedAt;
|
|
2233
|
-
permissions;
|
|
2234
2778
|
avatarHash;
|
|
2235
2779
|
premiumSince;
|
|
2236
2780
|
timedOutUntil;
|
|
2237
2781
|
flags;
|
|
2238
|
-
|
|
2782
|
+
#suppliedPermissions;
|
|
2783
|
+
#context;
|
|
2784
|
+
constructor(data, context) {
|
|
2239
2785
|
this.user = new User(data.user);
|
|
2786
|
+
this.#context = context;
|
|
2240
2787
|
if (!/^\d{1,20}$/.test(data.guild_id))
|
|
2241
2788
|
throw new TypeError("Member guild_id must be a valid snowflake.");
|
|
2242
2789
|
this.guildId = data.guild_id;
|
|
@@ -2246,12 +2793,53 @@ class GuildMember {
|
|
|
2246
2793
|
this.joinedAt = data.joined_at ? new Date(data.joined_at) : undefined;
|
|
2247
2794
|
if (this.joinedAt?.toString() === "Invalid Date")
|
|
2248
2795
|
throw new RangeError("Member joined_at must be a valid date.");
|
|
2249
|
-
|
|
2796
|
+
if (data.permissions !== undefined)
|
|
2797
|
+
this.#suppliedPermissions = new PermissionsBitField(data.permissions);
|
|
2250
2798
|
this.avatarHash = data.avatar ?? null;
|
|
2251
2799
|
this.premiumSince = toDateOrNull(data.premium_since);
|
|
2252
2800
|
this.timedOutUntil = toDateOrNull(data.communication_disabled_until);
|
|
2253
2801
|
this.flags = data.flags ?? 0;
|
|
2254
2802
|
}
|
|
2803
|
+
get permissions() {
|
|
2804
|
+
if (this.#suppliedPermissions)
|
|
2805
|
+
return this.#suppliedPermissions;
|
|
2806
|
+
return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds) ?? 0n);
|
|
2807
|
+
}
|
|
2808
|
+
permissionsIn(channelId) {
|
|
2809
|
+
const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId);
|
|
2810
|
+
return computed ? new PermissionsBitField(computed) : null;
|
|
2811
|
+
}
|
|
2812
|
+
#action(name) {
|
|
2813
|
+
const action = this.#context?.[name];
|
|
2814
|
+
if (!action)
|
|
2815
|
+
throw new Error("This member is not attached to a client.");
|
|
2816
|
+
return action;
|
|
2817
|
+
}
|
|
2818
|
+
kick(reason) {
|
|
2819
|
+
return this.#action("kickMember")(this.guildId, this.user.id, reason);
|
|
2820
|
+
}
|
|
2821
|
+
ban(options = {}) {
|
|
2822
|
+
return this.#action("banMember")(this.guildId, this.user.id, options);
|
|
2823
|
+
}
|
|
2824
|
+
edit(options, reason) {
|
|
2825
|
+
return this.#action("editMember")(this.guildId, this.user.id, options, reason);
|
|
2826
|
+
}
|
|
2827
|
+
timeout(milliseconds, reason) {
|
|
2828
|
+
if (milliseconds !== null && !(milliseconds > 0))
|
|
2829
|
+
throw new RangeError("Timeout length must be a positive number of milliseconds.");
|
|
2830
|
+
return this.edit({
|
|
2831
|
+
communication_disabled_until: milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString()
|
|
2832
|
+
}, reason);
|
|
2833
|
+
}
|
|
2834
|
+
setNickname(nickname, reason) {
|
|
2835
|
+
return this.edit({ nick: nickname }, reason);
|
|
2836
|
+
}
|
|
2837
|
+
addRole(roleId, reason) {
|
|
2838
|
+
return this.#action("addMemberRole")(this.guildId, this.user.id, roleId, reason);
|
|
2839
|
+
}
|
|
2840
|
+
removeRole(roleId, reason) {
|
|
2841
|
+
return this.#action("removeMemberRole")(this.guildId, this.user.id, roleId, reason);
|
|
2842
|
+
}
|
|
2255
2843
|
get displayName() {
|
|
2256
2844
|
return this.nickname ?? this.user.displayName;
|
|
2257
2845
|
}
|
|
@@ -2785,6 +3373,17 @@ class CommandOptions {
|
|
|
2785
3373
|
throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
|
|
2786
3374
|
return resolved;
|
|
2787
3375
|
}
|
|
3376
|
+
getMentionableType(name) {
|
|
3377
|
+
const opt = this.#get(name);
|
|
3378
|
+
if (!opt || opt.type !== OptionType.Mentionable)
|
|
3379
|
+
return null;
|
|
3380
|
+
const id = String(opt.value);
|
|
3381
|
+
if (this.#resolved?.users?.[id])
|
|
3382
|
+
return "user";
|
|
3383
|
+
if (this.#resolved?.roles?.[id])
|
|
3384
|
+
return "role";
|
|
3385
|
+
return null;
|
|
3386
|
+
}
|
|
2788
3387
|
getAttachment(name, required = false) {
|
|
2789
3388
|
const opt = this.#get(name);
|
|
2790
3389
|
if (!opt || opt.type !== OptionType.Attachment) {
|
|
@@ -2810,6 +3409,17 @@ var InteractionType = {
|
|
|
2810
3409
|
ApplicationCommandAutocomplete: 4,
|
|
2811
3410
|
ModalSubmit: 5
|
|
2812
3411
|
};
|
|
3412
|
+
var EPHEMERAL = 64;
|
|
3413
|
+
var TOKEN_LIFETIME_MS = 15 * 60000;
|
|
3414
|
+
var DISCORD_EPOCH = 1420070400000n;
|
|
3415
|
+
function toMessageData(options) {
|
|
3416
|
+
if (typeof options === "string")
|
|
3417
|
+
return { content: options };
|
|
3418
|
+
const { ephemeral, ...data } = options;
|
|
3419
|
+
if (ephemeral)
|
|
3420
|
+
data.flags = (typeof data.flags === "number" ? data.flags : 0) | EPHEMERAL;
|
|
3421
|
+
return data;
|
|
3422
|
+
}
|
|
2813
3423
|
|
|
2814
3424
|
class InteractionResponse {
|
|
2815
3425
|
type;
|
|
@@ -2824,14 +3434,10 @@ class InteractionResponse {
|
|
|
2824
3434
|
return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
|
|
2825
3435
|
}
|
|
2826
3436
|
static message(options) {
|
|
2827
|
-
|
|
2828
|
-
if (options.ephemeral) {
|
|
2829
|
-
data.flags = (typeof options.flags === "number" ? options.flags : 0) | 64;
|
|
2830
|
-
}
|
|
2831
|
-
return new InteractionResponse(InteractionResponseType.ChannelMessage, data);
|
|
3437
|
+
return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
|
|
2832
3438
|
}
|
|
2833
3439
|
static defer(ephemeral = false) {
|
|
2834
|
-
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags:
|
|
3440
|
+
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
|
|
2835
3441
|
}
|
|
2836
3442
|
static pong() {
|
|
2837
3443
|
return new InteractionResponse(InteractionResponseType.Pong);
|
|
@@ -2849,6 +3455,7 @@ class Interaction {
|
|
|
2849
3455
|
replied = false;
|
|
2850
3456
|
deferred = false;
|
|
2851
3457
|
#client;
|
|
3458
|
+
#acknowledging = false;
|
|
2852
3459
|
constructor(client, data) {
|
|
2853
3460
|
if (!data.id || !data.token)
|
|
2854
3461
|
throw new TypeError("Interaction ID and token are required.");
|
|
@@ -2864,6 +3471,20 @@ class Interaction {
|
|
|
2864
3471
|
isChatInputCommand() {
|
|
2865
3472
|
return this.type === InteractionType.ApplicationCommand;
|
|
2866
3473
|
}
|
|
3474
|
+
awaitModalSubmit(options) {
|
|
3475
|
+
const collect = this.#client.resourceContext?.collectInteractions;
|
|
3476
|
+
if (!collect)
|
|
3477
|
+
return Promise.reject(new Error("This interaction is not attached to a client."));
|
|
3478
|
+
if (!(options.time > 0))
|
|
3479
|
+
return Promise.reject(new RangeError("awaitModalSubmit needs a positive time."));
|
|
3480
|
+
const userId = this.user?.id;
|
|
3481
|
+
const collector = collect({
|
|
3482
|
+
time: options.time,
|
|
3483
|
+
max: 1,
|
|
3484
|
+
filter: async (interaction) => interaction.isModalSubmit() && interaction.user?.id === userId && (options.customId === undefined || interaction.customId === options.customId) && (options.filter ? await options.filter(interaction) : true)
|
|
3485
|
+
});
|
|
3486
|
+
return collector.next();
|
|
3487
|
+
}
|
|
2867
3488
|
isMessageComponent() {
|
|
2868
3489
|
return this.type === InteractionType.MessageComponent;
|
|
2869
3490
|
}
|
|
@@ -2898,9 +3519,57 @@ class Interaction {
|
|
|
2898
3519
|
return [3, 5, 6, 7, 8].includes(this.#componentType());
|
|
2899
3520
|
}
|
|
2900
3521
|
assertUnacknowledged() {
|
|
2901
|
-
if (this.replied || this.deferred)
|
|
3522
|
+
if (this.replied || this.deferred || this.#acknowledging)
|
|
2902
3523
|
throw new Error("Interaction has already been acknowledged.");
|
|
2903
3524
|
}
|
|
3525
|
+
async acknowledge(response, state) {
|
|
3526
|
+
this.assertUnacknowledged();
|
|
3527
|
+
this.#acknowledging = true;
|
|
3528
|
+
try {
|
|
3529
|
+
const result = await this.postResponse(response);
|
|
3530
|
+
this[state] = true;
|
|
3531
|
+
return result;
|
|
3532
|
+
} finally {
|
|
3533
|
+
this.#acknowledging = false;
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
get user() {
|
|
3537
|
+
const raw = this.data.member?.user ?? this.data.user;
|
|
3538
|
+
return raw ? new User(raw) : null;
|
|
3539
|
+
}
|
|
3540
|
+
get member() {
|
|
3541
|
+
const raw = this.data.member;
|
|
3542
|
+
if (!raw || !this.guildId)
|
|
3543
|
+
return null;
|
|
3544
|
+
return new GuildMember({
|
|
3545
|
+
...raw,
|
|
3546
|
+
guild_id: this.guildId
|
|
3547
|
+
}, this.#client.resourceContext);
|
|
3548
|
+
}
|
|
3549
|
+
get createdTimestamp() {
|
|
3550
|
+
return Number((BigInt(this.id) >> 22n) + DISCORD_EPOCH);
|
|
3551
|
+
}
|
|
3552
|
+
get expiresAt() {
|
|
3553
|
+
return new Date(this.createdTimestamp + TOKEN_LIFETIME_MS);
|
|
3554
|
+
}
|
|
3555
|
+
get isExpired() {
|
|
3556
|
+
return Date.now() >= this.createdTimestamp + TOKEN_LIFETIME_MS;
|
|
3557
|
+
}
|
|
3558
|
+
#webhookMessage(method, messageId, data) {
|
|
3559
|
+
if (!this.#client.interactionWebhookMessage)
|
|
3560
|
+
return Promise.reject(new Error("This interaction client does not support webhook message access."));
|
|
3561
|
+
return this.#client.interactionWebhookMessage(method, this.applicationId, this.token, messageId, data);
|
|
3562
|
+
}
|
|
3563
|
+
fetchReply() {
|
|
3564
|
+
this.assertAcknowledged();
|
|
3565
|
+
return this.#webhookMessage("GET", "@original");
|
|
3566
|
+
}
|
|
3567
|
+
editFollowUp(messageId, options) {
|
|
3568
|
+
return this.#webhookMessage("PATCH", messageId, toMessageData(options));
|
|
3569
|
+
}
|
|
3570
|
+
async deleteFollowUp(messageId) {
|
|
3571
|
+
await this.#webhookMessage("DELETE", messageId);
|
|
3572
|
+
}
|
|
2904
3573
|
assertAcknowledged() {
|
|
2905
3574
|
if (!this.replied && !this.deferred)
|
|
2906
3575
|
throw new Error("Interaction has not been acknowledged.");
|
|
@@ -2909,41 +3578,29 @@ class Interaction {
|
|
|
2909
3578
|
return this.#client.postInteractionResponse(this.id, this.token, response);
|
|
2910
3579
|
}
|
|
2911
3580
|
async reply(options) {
|
|
2912
|
-
this.
|
|
2913
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2914
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.message(payload));
|
|
2915
|
-
this.replied = true;
|
|
2916
|
-
return result;
|
|
3581
|
+
return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
|
|
2917
3582
|
}
|
|
2918
|
-
async deferReply(
|
|
2919
|
-
|
|
2920
|
-
await this
|
|
2921
|
-
this.deferred = true;
|
|
3583
|
+
async deferReply(options = false) {
|
|
3584
|
+
const ephemeral = typeof options === "boolean" ? options : options.ephemeral === true;
|
|
3585
|
+
await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
|
|
2922
3586
|
}
|
|
2923
3587
|
editReply(options) {
|
|
2924
3588
|
this.assertAcknowledged();
|
|
2925
|
-
return this.#client.editInteractionReply(this.token, options);
|
|
3589
|
+
return this.#client.editInteractionReply(this.token, toMessageData(options));
|
|
2926
3590
|
}
|
|
2927
3591
|
deleteReply() {
|
|
2928
3592
|
this.assertAcknowledged();
|
|
2929
3593
|
return this.#client.deleteInteractionReply(this.token);
|
|
2930
3594
|
}
|
|
2931
3595
|
followUp(options) {
|
|
2932
|
-
|
|
2933
|
-
return this.#client.followUpInteraction(this.token, payload);
|
|
3596
|
+
return this.#client.followUpInteraction(this.token, toMessageData(options));
|
|
2934
3597
|
}
|
|
2935
3598
|
async update(options) {
|
|
2936
|
-
this.
|
|
2937
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2938
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
|
|
2939
|
-
this.replied = true;
|
|
2940
|
-
return result;
|
|
3599
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2941
3600
|
}
|
|
2942
3601
|
async showModal(modal) {
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
this.replied = true;
|
|
2946
|
-
return result;
|
|
3602
|
+
const data = "toJSON" in modal && typeof modal.toJSON === "function" ? modal.toJSON() : modal;
|
|
3603
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, data), "replied");
|
|
2947
3604
|
}
|
|
2948
3605
|
}
|
|
2949
3606
|
|
|
@@ -2964,6 +3621,9 @@ class ComponentInteraction extends Interaction {
|
|
|
2964
3621
|
get customId() {
|
|
2965
3622
|
return this.data?.data?.custom_id ?? "";
|
|
2966
3623
|
}
|
|
3624
|
+
get messageId() {
|
|
3625
|
+
return this.data?.message?.id;
|
|
3626
|
+
}
|
|
2967
3627
|
get componentType() {
|
|
2968
3628
|
return this.data?.data?.component_type ?? 0;
|
|
2969
3629
|
}
|
|
@@ -2971,16 +3631,10 @@ class ComponentInteraction extends Interaction {
|
|
|
2971
3631
|
return this.data?.data?.values ?? [];
|
|
2972
3632
|
}
|
|
2973
3633
|
async deferUpdate() {
|
|
2974
|
-
this.
|
|
2975
|
-
await this.postResponse(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate));
|
|
2976
|
-
this.deferred = true;
|
|
3634
|
+
await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
|
|
2977
3635
|
}
|
|
2978
3636
|
async update(options) {
|
|
2979
|
-
this.
|
|
2980
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2981
|
-
const result = await this.postResponse(new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
|
|
2982
|
-
this.replied = true;
|
|
2983
|
-
return result;
|
|
3637
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2984
3638
|
}
|
|
2985
3639
|
}
|
|
2986
3640
|
|
|
@@ -3023,8 +3677,7 @@ class AutocompleteInteraction extends Interaction {
|
|
|
3023
3677
|
if (!Array.isArray(choices))
|
|
3024
3678
|
throw new TypeError("Autocomplete choices must be an array.");
|
|
3025
3679
|
const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
|
|
3026
|
-
await this.
|
|
3027
|
-
this.replied = true;
|
|
3680
|
+
await this.acknowledge(response, "replied");
|
|
3028
3681
|
}
|
|
3029
3682
|
}
|
|
3030
3683
|
function findFocused(options) {
|
|
@@ -3221,6 +3874,7 @@ class AuditLog {
|
|
|
3221
3874
|
}
|
|
3222
3875
|
|
|
3223
3876
|
// packages/structures/src/index.ts
|
|
3877
|
+
var COMPONENT_COLLECTOR_DEFAULT_TIME = 15 * 60000;
|
|
3224
3878
|
var NON_SYSTEM_MESSAGE_TYPES = new Set([0, 19, 20, 23]);
|
|
3225
3879
|
|
|
3226
3880
|
class Message extends BaseStructure {
|
|
@@ -3241,6 +3895,7 @@ class Message extends BaseStructure {
|
|
|
3241
3895
|
reference;
|
|
3242
3896
|
components;
|
|
3243
3897
|
referencedMessage;
|
|
3898
|
+
member;
|
|
3244
3899
|
#context;
|
|
3245
3900
|
constructor(data, context) {
|
|
3246
3901
|
super(data.id);
|
|
@@ -3263,6 +3918,11 @@ class Message extends BaseStructure {
|
|
|
3263
3918
|
this.reference = data.message_reference;
|
|
3264
3919
|
this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
|
|
3265
3920
|
this.#context = context;
|
|
3921
|
+
this.member = data.member && data.guild_id ? new GuildMember({
|
|
3922
|
+
...data.member,
|
|
3923
|
+
user: data.member.user ?? data.author,
|
|
3924
|
+
guild_id: data.guild_id
|
|
3925
|
+
}, context) : null;
|
|
3266
3926
|
this.channel = new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context);
|
|
3267
3927
|
}
|
|
3268
3928
|
get embedsSuppressed() {
|
|
@@ -3303,6 +3963,20 @@ class Message extends BaseStructure {
|
|
|
3303
3963
|
throw new Error("This message is not attached to a client.");
|
|
3304
3964
|
return this.#context.crosspostMessage(this.channelId, this.id);
|
|
3305
3965
|
}
|
|
3966
|
+
createComponentCollector(options = {}) {
|
|
3967
|
+
const collect = this.#context?.collectInteractions;
|
|
3968
|
+
if (!collect)
|
|
3969
|
+
throw new Error("This message is not attached to a client.");
|
|
3970
|
+
const { componentType, filter, ...rest } = options;
|
|
3971
|
+
return collect({
|
|
3972
|
+
...rest,
|
|
3973
|
+
time: rest.time ?? (rest.idle ? undefined : COMPONENT_COLLECTOR_DEFAULT_TIME),
|
|
3974
|
+
filter: async (interaction) => interaction.isMessageComponent() && interaction.messageId === this.id && (componentType === undefined || interaction.componentType === componentType) && (filter ? await filter(interaction) : true)
|
|
3975
|
+
});
|
|
3976
|
+
}
|
|
3977
|
+
awaitComponent(options = {}) {
|
|
3978
|
+
return this.createComponentCollector({ ...options, max: 1 }).next();
|
|
3979
|
+
}
|
|
3306
3980
|
react(emoji) {
|
|
3307
3981
|
if (!this.#context?.addReaction)
|
|
3308
3982
|
throw new Error("This message is not attached to a client.");
|
|
@@ -3376,23 +4050,43 @@ class Message extends BaseStructure {
|
|
|
3376
4050
|
}
|
|
3377
4051
|
|
|
3378
4052
|
// packages/managers/src/message.ts
|
|
4053
|
+
function toRequest(options) {
|
|
4054
|
+
const { files, ...body } = options;
|
|
4055
|
+
if (!files?.length)
|
|
4056
|
+
return body;
|
|
4057
|
+
return {
|
|
4058
|
+
body,
|
|
4059
|
+
files: files.map((file) => ({
|
|
4060
|
+
name: file.name,
|
|
4061
|
+
data: typeof file.data === "string" ? new TextEncoder().encode(file.data) : file.data,
|
|
4062
|
+
contentType: file.contentType
|
|
4063
|
+
}))
|
|
4064
|
+
};
|
|
4065
|
+
}
|
|
4066
|
+
|
|
3379
4067
|
class MessageManager {
|
|
3380
|
-
cache
|
|
4068
|
+
cache;
|
|
4069
|
+
#caching;
|
|
3381
4070
|
#rest;
|
|
3382
4071
|
#context;
|
|
3383
4072
|
#channelId;
|
|
3384
|
-
constructor(rest, context, channelId) {
|
|
4073
|
+
constructor(rest, context, channelId, cache) {
|
|
3385
4074
|
if (!channelId)
|
|
3386
4075
|
throw new TypeError("Channel ID is required.");
|
|
3387
4076
|
this.#rest = rest;
|
|
3388
4077
|
this.#context = context;
|
|
3389
4078
|
this.#channelId = channelId;
|
|
4079
|
+
this.#caching = cache !== undefined;
|
|
4080
|
+
this.cache = new Collection(null, {
|
|
4081
|
+
ttl: cache?.ttl,
|
|
4082
|
+
maxSize: cache ? cache.maxSize ?? 100 : undefined
|
|
4083
|
+
});
|
|
3390
4084
|
}
|
|
3391
4085
|
async resolve(messageId) {
|
|
3392
4086
|
return this.cache.get(messageId) ?? this.fetch(messageId);
|
|
3393
4087
|
}
|
|
3394
4088
|
async send(options) {
|
|
3395
|
-
const data = await this.#rest.post(Routes.channelMessages(this.#channelId), options);
|
|
4089
|
+
const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options));
|
|
3396
4090
|
return this.upsert(data);
|
|
3397
4091
|
}
|
|
3398
4092
|
async fetch(messageId) {
|
|
@@ -3403,13 +4097,14 @@ class MessageManager {
|
|
|
3403
4097
|
return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
|
|
3404
4098
|
}
|
|
3405
4099
|
upsert(data) {
|
|
3406
|
-
const existing = this.cache.
|
|
4100
|
+
const existing = this.cache.peek(data.id);
|
|
3407
4101
|
const message = new Message(data, this.#context);
|
|
3408
4102
|
if (existing) {
|
|
3409
4103
|
Object.assign(existing, message);
|
|
3410
4104
|
return existing;
|
|
3411
4105
|
}
|
|
3412
|
-
this
|
|
4106
|
+
if (this.#caching)
|
|
4107
|
+
this.cache.set(message.id, message);
|
|
3413
4108
|
return message;
|
|
3414
4109
|
}
|
|
3415
4110
|
delete(messageId) {
|
|
@@ -3463,17 +4158,58 @@ class UserManager extends ResourceManager {
|
|
|
3463
4158
|
});
|
|
3464
4159
|
}
|
|
3465
4160
|
}
|
|
3466
|
-
// packages/managers/src/
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
4161
|
+
// packages/managers/src/emoji.ts
|
|
4162
|
+
class EmojiManager extends Manager {
|
|
4163
|
+
#rest;
|
|
4164
|
+
#guildId;
|
|
4165
|
+
constructor(rest, guildId) {
|
|
4166
|
+
super();
|
|
4167
|
+
this.#rest = rest;
|
|
4168
|
+
this.#guildId = guildId;
|
|
4169
|
+
}
|
|
4170
|
+
fetch(emojiId) {
|
|
4171
|
+
return this.fetchOnce(emojiId, async () => new Emoji(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId))), (emoji) => this.#merge(emojiId, emoji));
|
|
4172
|
+
}
|
|
4173
|
+
async fetchAll() {
|
|
4174
|
+
const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
|
|
4175
|
+
return data.map((item) => this.upsert(item));
|
|
4176
|
+
}
|
|
4177
|
+
async create(options) {
|
|
4178
|
+
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
|
|
4179
|
+
}
|
|
4180
|
+
async edit(emojiId, options) {
|
|
4181
|
+
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
|
|
4182
|
+
}
|
|
4183
|
+
async deleteEmoji(emojiId) {
|
|
4184
|
+
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
|
|
4185
|
+
this.delete(emojiId);
|
|
4186
|
+
}
|
|
4187
|
+
upsert(data) {
|
|
4188
|
+
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
4189
|
+
return this.#merge(key, new Emoji(data));
|
|
4190
|
+
}
|
|
4191
|
+
#merge(key, emoji) {
|
|
4192
|
+
const existing = this.get(key);
|
|
4193
|
+
if (existing) {
|
|
4194
|
+
Object.assign(existing, emoji);
|
|
4195
|
+
return existing;
|
|
4196
|
+
}
|
|
4197
|
+
this.set(key, emoji);
|
|
4198
|
+
return emoji;
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4202
|
+
// packages/managers/src/advanced.ts
|
|
4203
|
+
function withQuery(path, query) {
|
|
4204
|
+
const params = new URLSearchParams;
|
|
4205
|
+
for (const [key, value] of Object.entries(query))
|
|
3470
4206
|
if (value !== undefined)
|
|
3471
|
-
|
|
3472
|
-
const suffix =
|
|
4207
|
+
params.set(key, String(value));
|
|
4208
|
+
const suffix = params.toString();
|
|
3473
4209
|
return suffix ? `${path}?${suffix}` : path;
|
|
3474
4210
|
}
|
|
3475
4211
|
|
|
3476
|
-
class
|
|
4212
|
+
class GuildStickerManager extends Manager {
|
|
3477
4213
|
#rest;
|
|
3478
4214
|
guildId;
|
|
3479
4215
|
constructor(rest, guildId) {
|
|
@@ -3481,21 +4217,273 @@ class GuildBanManager extends Manager {
|
|
|
3481
4217
|
this.#rest = rest;
|
|
3482
4218
|
this.guildId = guildId;
|
|
3483
4219
|
}
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
return ban;
|
|
4220
|
+
#store(sticker) {
|
|
4221
|
+
this.set(sticker.id, sticker);
|
|
4222
|
+
return sticker;
|
|
3488
4223
|
}
|
|
3489
|
-
async fetchAll(
|
|
3490
|
-
const
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
4224
|
+
async fetchAll() {
|
|
4225
|
+
const stickers = await this.#rest.get(Routes.guildSticker(this.guildId));
|
|
4226
|
+
this.clear();
|
|
4227
|
+
return stickers.map((sticker) => this.#store(sticker));
|
|
4228
|
+
}
|
|
4229
|
+
async fetch(stickerId) {
|
|
4230
|
+
return this.#store(await this.#rest.get(Routes.guildSticker(this.guildId, stickerId)));
|
|
4231
|
+
}
|
|
4232
|
+
async create(options) {
|
|
4233
|
+
const form = new FormData;
|
|
4234
|
+
form.set("name", options.name);
|
|
4235
|
+
form.set("description", options.description);
|
|
4236
|
+
form.set("tags", options.tags);
|
|
4237
|
+
form.set("file", options.file);
|
|
4238
|
+
return this.#store(await this.#rest.post(Routes.guildSticker(this.guildId), form, { reason: options.reason }));
|
|
4239
|
+
}
|
|
4240
|
+
async edit(stickerId, options) {
|
|
4241
|
+
const { reason, ...body } = options;
|
|
4242
|
+
return this.#store(await this.#rest.patch(Routes.guildSticker(this.guildId, stickerId), body, { reason }));
|
|
4243
|
+
}
|
|
4244
|
+
async remove(stickerId, reason) {
|
|
4245
|
+
await this.#rest.delete(Routes.guildSticker(this.guildId, stickerId), {
|
|
4246
|
+
reason
|
|
4247
|
+
});
|
|
4248
|
+
this.delete(stickerId);
|
|
4249
|
+
}
|
|
4250
|
+
sync(stickers) {
|
|
4251
|
+
this.clear();
|
|
4252
|
+
for (const sticker of stickers)
|
|
4253
|
+
this.#store(sticker);
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
class GuildSoundboardManager extends Manager {
|
|
4258
|
+
#rest;
|
|
4259
|
+
guildId;
|
|
4260
|
+
constructor(rest, guildId) {
|
|
4261
|
+
super();
|
|
4262
|
+
this.#rest = rest;
|
|
4263
|
+
this.guildId = guildId;
|
|
4264
|
+
}
|
|
4265
|
+
#store(sound) {
|
|
4266
|
+
this.set(sound.sound_id, sound);
|
|
4267
|
+
return sound;
|
|
4268
|
+
}
|
|
4269
|
+
async fetchAll() {
|
|
4270
|
+
const { items } = await this.#rest.get(Routes.guildSoundboardSound(this.guildId));
|
|
4271
|
+
this.clear();
|
|
4272
|
+
return items.map((sound) => this.#store(sound));
|
|
4273
|
+
}
|
|
4274
|
+
async fetch(soundId) {
|
|
4275
|
+
return this.#store(await this.#rest.get(Routes.guildSoundboardSound(this.guildId, soundId)));
|
|
4276
|
+
}
|
|
4277
|
+
async create(options) {
|
|
4278
|
+
if (options.volume !== undefined && (options.volume < 0 || options.volume > 1))
|
|
4279
|
+
throw new RangeError("Soundboard volume must be between 0 and 1.");
|
|
4280
|
+
return this.#store(await this.#rest.post(Routes.guildSoundboardSound(this.guildId), {
|
|
4281
|
+
name: options.name,
|
|
4282
|
+
sound: options.sound,
|
|
4283
|
+
volume: options.volume,
|
|
4284
|
+
emoji_id: options.emojiId,
|
|
4285
|
+
emoji_name: options.emojiName
|
|
4286
|
+
}, { reason: options.reason }));
|
|
4287
|
+
}
|
|
4288
|
+
async edit(soundId, options) {
|
|
4289
|
+
return this.#store(await this.#rest.patch(Routes.guildSoundboardSound(this.guildId, soundId), {
|
|
4290
|
+
name: options.name,
|
|
4291
|
+
volume: options.volume,
|
|
4292
|
+
emoji_id: options.emojiId,
|
|
4293
|
+
emoji_name: options.emojiName
|
|
4294
|
+
}, { reason: options.reason }));
|
|
4295
|
+
}
|
|
4296
|
+
async remove(soundId, reason) {
|
|
4297
|
+
await this.#rest.delete(Routes.guildSoundboardSound(this.guildId, soundId), { reason });
|
|
4298
|
+
this.delete(soundId);
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
4301
|
+
|
|
4302
|
+
class MonetizationManager extends Manager {
|
|
4303
|
+
#rest;
|
|
4304
|
+
applicationId;
|
|
4305
|
+
constructor(rest, applicationId) {
|
|
4306
|
+
super();
|
|
4307
|
+
this.#rest = rest;
|
|
4308
|
+
this.applicationId = applicationId;
|
|
4309
|
+
}
|
|
4310
|
+
fetchSkus() {
|
|
4311
|
+
return this.#rest.get(Routes.applicationSkus(this.applicationId));
|
|
4312
|
+
}
|
|
4313
|
+
async fetchEntitlements(query = {}) {
|
|
4314
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 100))
|
|
4315
|
+
throw new RangeError("Entitlement limit must be 1-100.");
|
|
4316
|
+
const entitlements = await this.#rest.get(withQuery(Routes.applicationEntitlement(this.applicationId), {
|
|
4317
|
+
user_id: query.userId,
|
|
4318
|
+
sku_ids: query.skuIds?.join(","),
|
|
4319
|
+
guild_id: query.guildId,
|
|
4320
|
+
before: query.before,
|
|
4321
|
+
after: query.after,
|
|
4322
|
+
limit: query.limit,
|
|
4323
|
+
exclude_ended: query.excludeEnded,
|
|
4324
|
+
exclude_deleted: query.excludeDeleted
|
|
4325
|
+
}));
|
|
4326
|
+
for (const entitlement of entitlements)
|
|
4327
|
+
this.set(entitlement.id, entitlement);
|
|
4328
|
+
return entitlements;
|
|
4329
|
+
}
|
|
4330
|
+
async fetch(entitlementId) {
|
|
4331
|
+
const entitlement = await this.#rest.get(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
4332
|
+
this.set(entitlement.id, entitlement);
|
|
4333
|
+
return entitlement;
|
|
4334
|
+
}
|
|
4335
|
+
async consume(entitlementId) {
|
|
4336
|
+
await this.#rest.post(Routes.consumeEntitlement(this.applicationId, entitlementId));
|
|
4337
|
+
const cached = this.get(entitlementId);
|
|
4338
|
+
if (cached)
|
|
4339
|
+
cached.consumed = true;
|
|
4340
|
+
}
|
|
4341
|
+
async createTestEntitlement(options) {
|
|
4342
|
+
const entitlement = await this.#rest.post(Routes.applicationEntitlement(this.applicationId), {
|
|
4343
|
+
sku_id: options.skuId,
|
|
4344
|
+
owner_id: options.ownerId,
|
|
4345
|
+
owner_type: options.ownerType
|
|
4346
|
+
});
|
|
4347
|
+
this.set(entitlement.id, entitlement);
|
|
4348
|
+
return entitlement;
|
|
4349
|
+
}
|
|
4350
|
+
async deleteTestEntitlement(entitlementId) {
|
|
4351
|
+
await this.#rest.delete(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
4352
|
+
this.delete(entitlementId);
|
|
4353
|
+
}
|
|
4354
|
+
fetchSubscriptions(skuId, query = {}) {
|
|
4355
|
+
return this.#rest.get(withQuery(Routes.skuSubscription(skuId), {
|
|
4356
|
+
user_id: query.userId,
|
|
4357
|
+
before: query.before,
|
|
4358
|
+
after: query.after,
|
|
4359
|
+
limit: query.limit
|
|
4360
|
+
}));
|
|
4361
|
+
}
|
|
4362
|
+
fetchSubscription(skuId, subscriptionId) {
|
|
4363
|
+
return this.#rest.get(Routes.skuSubscription(skuId, subscriptionId));
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
|
|
4367
|
+
// packages/managers/src/member.ts
|
|
4368
|
+
class GuildMemberManager extends ResourceManager {
|
|
4369
|
+
#rest;
|
|
4370
|
+
#context;
|
|
4371
|
+
guildId;
|
|
4372
|
+
constructor(guildId, rest, context = () => {
|
|
4373
|
+
return;
|
|
4374
|
+
}) {
|
|
4375
|
+
super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId }, context())), (member) => member.user.id);
|
|
4376
|
+
this.guildId = guildId;
|
|
4377
|
+
this.#rest = rest;
|
|
4378
|
+
this.#context = context;
|
|
4379
|
+
}
|
|
4380
|
+
async kick(userId, reason) {
|
|
4381
|
+
await this.#rest.delete(Routes.guildMember(this.guildId, userId), {
|
|
4382
|
+
reason
|
|
4383
|
+
});
|
|
4384
|
+
this.delete(userId);
|
|
4385
|
+
}
|
|
4386
|
+
async ban(userId, options = {}) {
|
|
4387
|
+
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
4388
|
+
this.delete(userId);
|
|
4389
|
+
}
|
|
4390
|
+
async unban(userId) {
|
|
4391
|
+
await this.#rest.delete(Routes.guildBan(this.guildId, userId));
|
|
4392
|
+
}
|
|
4393
|
+
async edit(userId, options, reason) {
|
|
4394
|
+
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options, { reason });
|
|
4395
|
+
const member = new GuildMember({ ...data, guild_id: this.guildId }, this.#context());
|
|
4396
|
+
this.set(member.user.id, member);
|
|
4397
|
+
return member;
|
|
4398
|
+
}
|
|
4399
|
+
async addRole(userId, roleId, reason) {
|
|
4400
|
+
await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId), undefined, { reason });
|
|
4401
|
+
}
|
|
4402
|
+
async removeRole(userId, roleId, reason) {
|
|
4403
|
+
await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId), { reason });
|
|
4404
|
+
}
|
|
4405
|
+
async timeout(userId, milliseconds, reason) {
|
|
4406
|
+
const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
|
|
4407
|
+
return this.edit(userId, { communication_disabled_until: timeoutDate }, reason);
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
|
|
4411
|
+
// packages/managers/src/role.ts
|
|
4412
|
+
class RoleManager extends ResourceManager {
|
|
4413
|
+
#rest;
|
|
4414
|
+
guildId;
|
|
4415
|
+
constructor(guildId, rest) {
|
|
4416
|
+
super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
|
|
4417
|
+
this.guildId = guildId;
|
|
4418
|
+
this.#rest = rest;
|
|
4419
|
+
}
|
|
4420
|
+
async fetchAll() {
|
|
4421
|
+
const data = await this.#rest.get(Routes.guildRoles(this.guildId));
|
|
4422
|
+
return data.map((item) => {
|
|
4423
|
+
const role = new Role(item);
|
|
4424
|
+
this.set(role.id, role);
|
|
4425
|
+
return role;
|
|
4426
|
+
});
|
|
4427
|
+
}
|
|
4428
|
+
async create(options) {
|
|
4429
|
+
const { reason, ...payload } = options;
|
|
4430
|
+
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
4431
|
+
...payload,
|
|
4432
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
4433
|
+
});
|
|
4434
|
+
const role = new Role(data);
|
|
4435
|
+
this.set(role.id, role);
|
|
4436
|
+
return role;
|
|
4437
|
+
}
|
|
4438
|
+
async edit(roleId, options) {
|
|
4439
|
+
const { reason, ...payload } = options;
|
|
4440
|
+
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
4441
|
+
...payload,
|
|
4442
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
4443
|
+
});
|
|
4444
|
+
const role = new Role(data);
|
|
4445
|
+
this.set(role.id, role);
|
|
4446
|
+
return role;
|
|
4447
|
+
}
|
|
4448
|
+
async deleteRole(roleId) {
|
|
4449
|
+
await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
|
|
4450
|
+
this.delete(roleId);
|
|
4451
|
+
}
|
|
4452
|
+
}
|
|
4453
|
+
|
|
4454
|
+
// packages/managers/src/guild-resources.ts
|
|
4455
|
+
function withQuery2(path, params) {
|
|
4456
|
+
const query = new URLSearchParams;
|
|
4457
|
+
for (const [key, value] of Object.entries(params))
|
|
4458
|
+
if (value !== undefined)
|
|
4459
|
+
query.set(key, String(value));
|
|
4460
|
+
const suffix = query.toString();
|
|
4461
|
+
return suffix ? `${path}?${suffix}` : path;
|
|
4462
|
+
}
|
|
4463
|
+
|
|
4464
|
+
class GuildBanManager extends Manager {
|
|
4465
|
+
#rest;
|
|
4466
|
+
guildId;
|
|
4467
|
+
constructor(rest, guildId) {
|
|
4468
|
+
super();
|
|
4469
|
+
this.#rest = rest;
|
|
4470
|
+
this.guildId = guildId;
|
|
4471
|
+
}
|
|
4472
|
+
async fetch(userId) {
|
|
4473
|
+
const ban = await this.#rest.get(Routes.guildBan(this.guildId, userId));
|
|
4474
|
+
this.set(ban.user.id, ban);
|
|
4475
|
+
return ban;
|
|
4476
|
+
}
|
|
4477
|
+
async fetchAll(options = {}) {
|
|
4478
|
+
const limit = options.limit === undefined ? undefined : Math.min(1000, Math.max(1, options.limit));
|
|
4479
|
+
const bans = await this.#rest.get(withQuery2(Routes.guildBans(this.guildId), {
|
|
4480
|
+
limit,
|
|
4481
|
+
before: options.before,
|
|
4482
|
+
after: options.after
|
|
4483
|
+
}));
|
|
4484
|
+
for (const ban of bans)
|
|
4485
|
+
this.set(ban.user.id, ban);
|
|
4486
|
+
return bans;
|
|
3499
4487
|
}
|
|
3500
4488
|
async create(userId, options = {}) {
|
|
3501
4489
|
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
@@ -3521,12 +4509,12 @@ class GuildScheduledEventManager extends Manager {
|
|
|
3521
4509
|
return event;
|
|
3522
4510
|
}
|
|
3523
4511
|
async fetch(eventId, options = {}) {
|
|
3524
|
-
return this.#store(await this.#rest.get(
|
|
4512
|
+
return this.#store(await this.#rest.get(withQuery2(Routes.guildScheduledEvent(this.guildId, eventId), {
|
|
3525
4513
|
with_user_count: options.withUserCount
|
|
3526
4514
|
})));
|
|
3527
4515
|
}
|
|
3528
4516
|
async fetchAll(options = {}) {
|
|
3529
|
-
const events = await this.#rest.get(
|
|
4517
|
+
const events = await this.#rest.get(withQuery2(Routes.guildScheduledEvents(this.guildId), {
|
|
3530
4518
|
with_user_count: options.withUserCount
|
|
3531
4519
|
}));
|
|
3532
4520
|
return events.map((event) => this.#store(event));
|
|
@@ -3543,7 +4531,7 @@ class GuildScheduledEventManager extends Manager {
|
|
|
3543
4531
|
}
|
|
3544
4532
|
async fetchSubscribers(eventId, options = {}) {
|
|
3545
4533
|
const limit = options.limit === undefined ? undefined : Math.min(100, Math.max(1, options.limit));
|
|
3546
|
-
return this.#rest.get(
|
|
4534
|
+
return this.#rest.get(withQuery2(Routes.guildScheduledEventUsers(this.guildId, eventId), {
|
|
3547
4535
|
limit,
|
|
3548
4536
|
with_member: options.withMember,
|
|
3549
4537
|
before: options.before,
|
|
@@ -3587,10 +4575,25 @@ class StageInstanceManager extends Manager {
|
|
|
3587
4575
|
|
|
3588
4576
|
class PermissionOverwriteManager {
|
|
3589
4577
|
#rest;
|
|
4578
|
+
#current;
|
|
3590
4579
|
channelId;
|
|
3591
|
-
constructor(rest, channelId) {
|
|
4580
|
+
constructor(rest, channelId, current = () => {
|
|
4581
|
+
return;
|
|
4582
|
+
}) {
|
|
3592
4583
|
this.#rest = rest;
|
|
3593
4584
|
this.channelId = channelId;
|
|
4585
|
+
this.#current = current;
|
|
4586
|
+
}
|
|
4587
|
+
async update(overwriteId, changes, options = {}) {
|
|
4588
|
+
const overwrites = this.#current() ?? (await this.#rest.get(Routes.channel(this.channelId))).permission_overwrites ?? [];
|
|
4589
|
+
const existing = overwrites.find((entry) => entry.id === overwriteId);
|
|
4590
|
+
const type = existing?.type ?? options.type;
|
|
4591
|
+
if (type !== 0 && type !== 1)
|
|
4592
|
+
throw new TypeError("A new permission overwrite needs a type: 0 for a role, 1 for a member.");
|
|
4593
|
+
const touched = (changes.allow ?? 0n) | (changes.deny ?? 0n) | (changes.inherit ?? 0n);
|
|
4594
|
+
const allow = BigInt(existing?.allow ?? 0) & ~touched | (changes.allow ?? 0n);
|
|
4595
|
+
const deny = BigInt(existing?.deny ?? 0) & ~touched | (changes.deny ?? 0n);
|
|
4596
|
+
await this.edit(overwriteId, { type, allow, deny }, options.reason);
|
|
3594
4597
|
}
|
|
3595
4598
|
async edit(overwriteId, options, reason) {
|
|
3596
4599
|
await this.#rest.put(Routes.channelPermission(this.channelId, overwriteId), {
|
|
@@ -3605,7 +4608,7 @@ class PermissionOverwriteManager {
|
|
|
3605
4608
|
}
|
|
3606
4609
|
|
|
3607
4610
|
// packages/managers/src/guild.ts
|
|
3608
|
-
function
|
|
4611
|
+
function withQuery3(path, params) {
|
|
3609
4612
|
const suffix = params.toString();
|
|
3610
4613
|
return suffix ? `${path}?${suffix}` : path;
|
|
3611
4614
|
}
|
|
@@ -3614,6 +4617,24 @@ class GuildManager extends ResourceManager {
|
|
|
3614
4617
|
#rest;
|
|
3615
4618
|
#bans = new Map;
|
|
3616
4619
|
#scheduledEvents = new Map;
|
|
4620
|
+
#members = new Map;
|
|
4621
|
+
#roles = new Map;
|
|
4622
|
+
#emojis = new Map;
|
|
4623
|
+
#stickers = new Map;
|
|
4624
|
+
#soundboard = new Map;
|
|
4625
|
+
#voiceStates = new Map;
|
|
4626
|
+
#autoModerationRules = new Map;
|
|
4627
|
+
#invites = new Map;
|
|
4628
|
+
#context;
|
|
4629
|
+
attachContext(context) {
|
|
4630
|
+
this.#context = context;
|
|
4631
|
+
}
|
|
4632
|
+
#perGuild(map, guildId, create) {
|
|
4633
|
+
let manager = map.get(guildId);
|
|
4634
|
+
if (!manager)
|
|
4635
|
+
map.set(guildId, manager = create());
|
|
4636
|
+
return manager;
|
|
4637
|
+
}
|
|
3617
4638
|
constructor(rest) {
|
|
3618
4639
|
super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
|
|
3619
4640
|
this.#rest = rest;
|
|
@@ -3630,6 +4651,68 @@ class GuildManager extends ResourceManager {
|
|
|
3630
4651
|
this.#scheduledEvents.set(guildId, manager = new GuildScheduledEventManager(this.#rest, guildId));
|
|
3631
4652
|
return manager;
|
|
3632
4653
|
}
|
|
4654
|
+
members(guildId) {
|
|
4655
|
+
let manager = this.#members.get(guildId);
|
|
4656
|
+
if (!manager)
|
|
4657
|
+
this.#members.set(guildId, manager = new GuildMemberManager(guildId, this.#rest, () => this.#context));
|
|
4658
|
+
return manager;
|
|
4659
|
+
}
|
|
4660
|
+
roles(guildId) {
|
|
4661
|
+
let manager = this.#roles.get(guildId);
|
|
4662
|
+
if (!manager)
|
|
4663
|
+
this.#roles.set(guildId, manager = new RoleManager(guildId, this.#rest));
|
|
4664
|
+
return manager;
|
|
4665
|
+
}
|
|
4666
|
+
emojis(guildId) {
|
|
4667
|
+
let manager = this.#emojis.get(guildId);
|
|
4668
|
+
if (!manager)
|
|
4669
|
+
this.#emojis.set(guildId, manager = new EmojiManager(this.#rest, guildId));
|
|
4670
|
+
return manager;
|
|
4671
|
+
}
|
|
4672
|
+
stickers(guildId) {
|
|
4673
|
+
let manager = this.#stickers.get(guildId);
|
|
4674
|
+
if (!manager)
|
|
4675
|
+
this.#stickers.set(guildId, manager = new GuildStickerManager(this.#rest, guildId));
|
|
4676
|
+
return manager;
|
|
4677
|
+
}
|
|
4678
|
+
soundboard(guildId) {
|
|
4679
|
+
let manager = this.#soundboard.get(guildId);
|
|
4680
|
+
if (!manager)
|
|
4681
|
+
this.#soundboard.set(guildId, manager = new GuildSoundboardManager(this.#rest, guildId));
|
|
4682
|
+
return manager;
|
|
4683
|
+
}
|
|
4684
|
+
voiceStates(guildId) {
|
|
4685
|
+
return this.#perGuild(this.#voiceStates, guildId, () => new Manager);
|
|
4686
|
+
}
|
|
4687
|
+
autoModerationRules(guildId) {
|
|
4688
|
+
return this.#perGuild(this.#autoModerationRules, guildId, () => new Manager);
|
|
4689
|
+
}
|
|
4690
|
+
invites(guildId) {
|
|
4691
|
+
return this.#perGuild(this.#invites, guildId, () => new Manager);
|
|
4692
|
+
}
|
|
4693
|
+
patch(data) {
|
|
4694
|
+
const guild = new Guild(data);
|
|
4695
|
+
const existing = this.get(guild.id);
|
|
4696
|
+
if (!existing)
|
|
4697
|
+
return this.upsert(guild);
|
|
4698
|
+
for (const [key, value] of Object.entries(guild))
|
|
4699
|
+
if (value !== undefined)
|
|
4700
|
+
existing[key] = value;
|
|
4701
|
+
return existing;
|
|
4702
|
+
}
|
|
4703
|
+
delete(id) {
|
|
4704
|
+
this.#bans.delete(id);
|
|
4705
|
+
this.#scheduledEvents.delete(id);
|
|
4706
|
+
this.#members.delete(id);
|
|
4707
|
+
this.#roles.delete(id);
|
|
4708
|
+
this.#emojis.delete(id);
|
|
4709
|
+
this.#stickers.delete(id);
|
|
4710
|
+
this.#soundboard.delete(id);
|
|
4711
|
+
this.#voiceStates.delete(id);
|
|
4712
|
+
this.#autoModerationRules.delete(id);
|
|
4713
|
+
this.#invites.delete(id);
|
|
4714
|
+
return super.delete(id);
|
|
4715
|
+
}
|
|
3633
4716
|
async create(options) {
|
|
3634
4717
|
const data = await this.#rest.post("/guilds", options);
|
|
3635
4718
|
return this.upsert(new Guild(data));
|
|
@@ -3665,7 +4748,7 @@ class GuildManager extends ResourceManager {
|
|
|
3665
4748
|
params.set("after", options.after);
|
|
3666
4749
|
if (options.limit !== undefined)
|
|
3667
4750
|
params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
|
|
3668
|
-
return this.#rest.get(
|
|
4751
|
+
return this.#rest.get(withQuery3(Routes.guildAuditLog(guildId), params));
|
|
3669
4752
|
}
|
|
3670
4753
|
async fetchMembers(guildId, options = {}) {
|
|
3671
4754
|
const params = new URLSearchParams;
|
|
@@ -3673,160 +4756,81 @@ class GuildManager extends ResourceManager {
|
|
|
3673
4756
|
params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
|
|
3674
4757
|
if (options.after)
|
|
3675
4758
|
params.set("after", options.after);
|
|
3676
|
-
return this.#rest.get(
|
|
4759
|
+
return this.#rest.get(withQuery3(Routes.guildMembers(guildId), params));
|
|
3677
4760
|
}
|
|
3678
4761
|
async fetchAutoModerationRules(guildId) {
|
|
3679
4762
|
const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
|
|
3680
4763
|
return rules.map((r) => new AutoModerationRule(r));
|
|
3681
4764
|
}
|
|
3682
4765
|
async fetchAutoModerationRule(guildId, ruleId) {
|
|
3683
|
-
const rule = await this.#rest.get(Routes.guildAutoModerationRule(guildId, ruleId));
|
|
3684
|
-
return new AutoModerationRule(rule);
|
|
3685
|
-
}
|
|
3686
|
-
async createAutoModerationRule(guildId, options) {
|
|
3687
|
-
const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), options);
|
|
3688
|
-
return new AutoModerationRule(rule);
|
|
3689
|
-
}
|
|
3690
|
-
async editAutoModerationRule(guildId, ruleId, options) {
|
|
3691
|
-
const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), options);
|
|
3692
|
-
return new AutoModerationRule(rule);
|
|
3693
|
-
}
|
|
3694
|
-
async deleteAutoModerationRule(guildId, ruleId) {
|
|
3695
|
-
await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId));
|
|
3696
|
-
}
|
|
3697
|
-
}
|
|
3698
|
-
var AuditLogEvent = {
|
|
3699
|
-
GuildUpdate: 1,
|
|
3700
|
-
ChannelCreate: 10,
|
|
3701
|
-
ChannelUpdate: 11,
|
|
3702
|
-
ChannelDelete: 12,
|
|
3703
|
-
ChannelOverwriteCreate: 13,
|
|
3704
|
-
ChannelOverwriteUpdate: 14,
|
|
3705
|
-
ChannelOverwriteDelete: 15,
|
|
3706
|
-
MemberKick: 20,
|
|
3707
|
-
MemberPrune: 21,
|
|
3708
|
-
MemberBanAdd: 22,
|
|
3709
|
-
MemberBanRemove: 23,
|
|
3710
|
-
MemberUpdate: 24,
|
|
3711
|
-
MemberRoleUpdate: 25,
|
|
3712
|
-
MemberMove: 26,
|
|
3713
|
-
MemberDisconnect: 27,
|
|
3714
|
-
BotAdd: 28,
|
|
3715
|
-
RoleCreate: 30,
|
|
3716
|
-
RoleUpdate: 31,
|
|
3717
|
-
RoleDelete: 32,
|
|
3718
|
-
InviteCreate: 40,
|
|
3719
|
-
InviteUpdate: 41,
|
|
3720
|
-
InviteDelete: 42,
|
|
3721
|
-
WebhookCreate: 50,
|
|
3722
|
-
WebhookUpdate: 51,
|
|
3723
|
-
WebhookDelete: 52,
|
|
3724
|
-
EmojiCreate: 60,
|
|
3725
|
-
EmojiUpdate: 61,
|
|
3726
|
-
EmojiDelete: 62,
|
|
3727
|
-
MessageDelete: 72,
|
|
3728
|
-
MessageBulkDelete: 73,
|
|
3729
|
-
MessagePin: 74,
|
|
3730
|
-
MessageUnpin: 75,
|
|
3731
|
-
IntegrationCreate: 80,
|
|
3732
|
-
IntegrationUpdate: 81,
|
|
3733
|
-
IntegrationDelete: 82,
|
|
3734
|
-
StageInstanceCreate: 83,
|
|
3735
|
-
StageInstanceUpdate: 84,
|
|
3736
|
-
StageInstanceDelete: 85,
|
|
3737
|
-
StickerCreate: 90,
|
|
3738
|
-
StickerUpdate: 91,
|
|
3739
|
-
StickerDelete: 92,
|
|
3740
|
-
ScheduledEventCreate: 100,
|
|
3741
|
-
ScheduledEventUpdate: 101,
|
|
3742
|
-
ScheduledEventDelete: 102,
|
|
3743
|
-
ThreadCreate: 110,
|
|
3744
|
-
ThreadUpdate: 111,
|
|
3745
|
-
ThreadDelete: 112,
|
|
3746
|
-
AutoModerationRuleCreate: 140,
|
|
3747
|
-
AutoModerationRuleUpdate: 141,
|
|
3748
|
-
AutoModerationRuleDelete: 142,
|
|
3749
|
-
AutoModerationBlockMessage: 143
|
|
3750
|
-
};
|
|
3751
|
-
// packages/managers/src/role.ts
|
|
3752
|
-
class RoleManager extends ResourceManager {
|
|
3753
|
-
#rest;
|
|
3754
|
-
guildId;
|
|
3755
|
-
constructor(guildId, rest) {
|
|
3756
|
-
super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
|
|
3757
|
-
this.guildId = guildId;
|
|
3758
|
-
this.#rest = rest;
|
|
3759
|
-
}
|
|
3760
|
-
async fetchAll() {
|
|
3761
|
-
const data = await this.#rest.get(Routes.guildRoles(this.guildId));
|
|
3762
|
-
return data.map((item) => {
|
|
3763
|
-
const role = new Role(item);
|
|
3764
|
-
this.set(role.id, role);
|
|
3765
|
-
return role;
|
|
3766
|
-
});
|
|
3767
|
-
}
|
|
3768
|
-
async create(options) {
|
|
3769
|
-
const { reason, ...payload } = options;
|
|
3770
|
-
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
3771
|
-
...payload,
|
|
3772
|
-
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3773
|
-
});
|
|
3774
|
-
const role = new Role(data);
|
|
3775
|
-
this.set(role.id, role);
|
|
3776
|
-
return role;
|
|
3777
|
-
}
|
|
3778
|
-
async edit(roleId, options) {
|
|
3779
|
-
const { reason, ...payload } = options;
|
|
3780
|
-
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
3781
|
-
...payload,
|
|
3782
|
-
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3783
|
-
});
|
|
3784
|
-
const role = new Role(data);
|
|
3785
|
-
this.set(role.id, role);
|
|
3786
|
-
return role;
|
|
3787
|
-
}
|
|
3788
|
-
async deleteRole(roleId) {
|
|
3789
|
-
await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
|
|
3790
|
-
this.delete(roleId);
|
|
3791
|
-
}
|
|
3792
|
-
}
|
|
3793
|
-
// packages/managers/src/member.ts
|
|
3794
|
-
class GuildMemberManager extends ResourceManager {
|
|
3795
|
-
#rest;
|
|
3796
|
-
guildId;
|
|
3797
|
-
constructor(guildId, rest) {
|
|
3798
|
-
super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId })), (member) => member.user.id);
|
|
3799
|
-
this.guildId = guildId;
|
|
3800
|
-
this.#rest = rest;
|
|
3801
|
-
}
|
|
3802
|
-
async kick(userId) {
|
|
3803
|
-
await this.#rest.delete(Routes.guildMember(this.guildId, userId));
|
|
3804
|
-
this.delete(userId);
|
|
3805
|
-
}
|
|
3806
|
-
async ban(userId, options = {}) {
|
|
3807
|
-
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
3808
|
-
this.delete(userId);
|
|
3809
|
-
}
|
|
3810
|
-
async unban(userId) {
|
|
3811
|
-
await this.#rest.delete(Routes.guildBan(this.guildId, userId));
|
|
3812
|
-
}
|
|
3813
|
-
async edit(userId, options) {
|
|
3814
|
-
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options);
|
|
3815
|
-
const member = new GuildMember({ ...data, guild_id: this.guildId });
|
|
3816
|
-
this.set(member.user.id, member);
|
|
3817
|
-
return member;
|
|
4766
|
+
const rule = await this.#rest.get(Routes.guildAutoModerationRule(guildId, ruleId));
|
|
4767
|
+
return new AutoModerationRule(rule);
|
|
3818
4768
|
}
|
|
3819
|
-
async
|
|
3820
|
-
await this.#rest.
|
|
4769
|
+
async createAutoModerationRule(guildId, options) {
|
|
4770
|
+
const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), options);
|
|
4771
|
+
return new AutoModerationRule(rule);
|
|
3821
4772
|
}
|
|
3822
|
-
async
|
|
3823
|
-
await this.#rest.
|
|
4773
|
+
async editAutoModerationRule(guildId, ruleId, options) {
|
|
4774
|
+
const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), options);
|
|
4775
|
+
return new AutoModerationRule(rule);
|
|
3824
4776
|
}
|
|
3825
|
-
async
|
|
3826
|
-
|
|
3827
|
-
return this.edit(userId, { communication_disabled_until: timeoutDate });
|
|
4777
|
+
async deleteAutoModerationRule(guildId, ruleId) {
|
|
4778
|
+
await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId));
|
|
3828
4779
|
}
|
|
3829
4780
|
}
|
|
4781
|
+
var AuditLogEvent = {
|
|
4782
|
+
GuildUpdate: 1,
|
|
4783
|
+
ChannelCreate: 10,
|
|
4784
|
+
ChannelUpdate: 11,
|
|
4785
|
+
ChannelDelete: 12,
|
|
4786
|
+
ChannelOverwriteCreate: 13,
|
|
4787
|
+
ChannelOverwriteUpdate: 14,
|
|
4788
|
+
ChannelOverwriteDelete: 15,
|
|
4789
|
+
MemberKick: 20,
|
|
4790
|
+
MemberPrune: 21,
|
|
4791
|
+
MemberBanAdd: 22,
|
|
4792
|
+
MemberBanRemove: 23,
|
|
4793
|
+
MemberUpdate: 24,
|
|
4794
|
+
MemberRoleUpdate: 25,
|
|
4795
|
+
MemberMove: 26,
|
|
4796
|
+
MemberDisconnect: 27,
|
|
4797
|
+
BotAdd: 28,
|
|
4798
|
+
RoleCreate: 30,
|
|
4799
|
+
RoleUpdate: 31,
|
|
4800
|
+
RoleDelete: 32,
|
|
4801
|
+
InviteCreate: 40,
|
|
4802
|
+
InviteUpdate: 41,
|
|
4803
|
+
InviteDelete: 42,
|
|
4804
|
+
WebhookCreate: 50,
|
|
4805
|
+
WebhookUpdate: 51,
|
|
4806
|
+
WebhookDelete: 52,
|
|
4807
|
+
EmojiCreate: 60,
|
|
4808
|
+
EmojiUpdate: 61,
|
|
4809
|
+
EmojiDelete: 62,
|
|
4810
|
+
MessageDelete: 72,
|
|
4811
|
+
MessageBulkDelete: 73,
|
|
4812
|
+
MessagePin: 74,
|
|
4813
|
+
MessageUnpin: 75,
|
|
4814
|
+
IntegrationCreate: 80,
|
|
4815
|
+
IntegrationUpdate: 81,
|
|
4816
|
+
IntegrationDelete: 82,
|
|
4817
|
+
StageInstanceCreate: 83,
|
|
4818
|
+
StageInstanceUpdate: 84,
|
|
4819
|
+
StageInstanceDelete: 85,
|
|
4820
|
+
StickerCreate: 90,
|
|
4821
|
+
StickerUpdate: 91,
|
|
4822
|
+
StickerDelete: 92,
|
|
4823
|
+
ScheduledEventCreate: 100,
|
|
4824
|
+
ScheduledEventUpdate: 101,
|
|
4825
|
+
ScheduledEventDelete: 102,
|
|
4826
|
+
ThreadCreate: 110,
|
|
4827
|
+
ThreadUpdate: 111,
|
|
4828
|
+
ThreadDelete: 112,
|
|
4829
|
+
AutoModerationRuleCreate: 140,
|
|
4830
|
+
AutoModerationRuleUpdate: 141,
|
|
4831
|
+
AutoModerationRuleDelete: 142,
|
|
4832
|
+
AutoModerationBlockMessage: 143
|
|
4833
|
+
};
|
|
3830
4834
|
// packages/managers/src/application.ts
|
|
3831
4835
|
class ApplicationCommandManager {
|
|
3832
4836
|
#rest;
|
|
@@ -3866,53 +4870,22 @@ class ApplicationCommandManager {
|
|
|
3866
4870
|
await this.#rest.delete(Routes.guildApplicationCommand(this.#applicationId, guildId, commandId));
|
|
3867
4871
|
}
|
|
3868
4872
|
}
|
|
3869
|
-
// packages/managers/src/emoji.ts
|
|
3870
|
-
class EmojiManager extends Manager {
|
|
3871
|
-
#rest;
|
|
3872
|
-
#guildId;
|
|
3873
|
-
constructor(rest, guildId) {
|
|
3874
|
-
super();
|
|
3875
|
-
this.#rest = rest;
|
|
3876
|
-
this.#guildId = guildId;
|
|
3877
|
-
}
|
|
3878
|
-
async fetch(emojiId) {
|
|
3879
|
-
return this.upsert(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId)));
|
|
3880
|
-
}
|
|
3881
|
-
async fetchAll() {
|
|
3882
|
-
const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
|
|
3883
|
-
return data.map((item) => this.upsert(item));
|
|
3884
|
-
}
|
|
3885
|
-
async create(options) {
|
|
3886
|
-
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
|
|
3887
|
-
}
|
|
3888
|
-
async edit(emojiId, options) {
|
|
3889
|
-
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
|
|
3890
|
-
}
|
|
3891
|
-
async deleteEmoji(emojiId) {
|
|
3892
|
-
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
|
|
3893
|
-
this.delete(emojiId);
|
|
3894
|
-
}
|
|
3895
|
-
upsert(data) {
|
|
3896
|
-
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
3897
|
-
const existing = this.get(key);
|
|
3898
|
-
const emoji = new Emoji(data);
|
|
3899
|
-
if (existing) {
|
|
3900
|
-
Object.assign(existing, emoji);
|
|
3901
|
-
return existing;
|
|
3902
|
-
}
|
|
3903
|
-
this.set(key, emoji);
|
|
3904
|
-
return emoji;
|
|
3905
|
-
}
|
|
3906
|
-
}
|
|
3907
4873
|
|
|
3908
4874
|
// packages/managers/src/index.ts
|
|
4875
|
+
var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
|
|
4876
|
+
function snowflakeTime(id) {
|
|
4877
|
+
return Number((BigInt(id) >> 22n) + 1420070400000n);
|
|
4878
|
+
}
|
|
4879
|
+
|
|
3909
4880
|
class ChannelManager extends Manager {
|
|
3910
4881
|
#rest;
|
|
3911
4882
|
#context;
|
|
3912
4883
|
#messageManagers = new Map;
|
|
3913
|
-
|
|
4884
|
+
#messageCache;
|
|
4885
|
+
constructor(rest, options = {}) {
|
|
3914
4886
|
super();
|
|
3915
4887
|
this.#rest = rest;
|
|
4888
|
+
this.#messageCache = options.messageCache;
|
|
3916
4889
|
this.#context = {
|
|
3917
4890
|
sendMessage: (channelId, options) => this.send(channelId, options),
|
|
3918
4891
|
editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
|
|
@@ -3931,27 +4904,29 @@ class ChannelManager extends Manager {
|
|
|
3931
4904
|
messages(channelId) {
|
|
3932
4905
|
let manager = this.#messageManagers.get(channelId);
|
|
3933
4906
|
if (!manager) {
|
|
3934
|
-
manager = new MessageManager(this.#rest, this.#context, channelId);
|
|
4907
|
+
manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
|
|
3935
4908
|
this.#messageManagers.set(channelId, manager);
|
|
3936
4909
|
}
|
|
3937
4910
|
return manager;
|
|
3938
4911
|
}
|
|
3939
4912
|
permissionOverwrites(channelId) {
|
|
3940
|
-
return new PermissionOverwriteManager(this.#rest, channelId);
|
|
4913
|
+
return new PermissionOverwriteManager(this.#rest, channelId, () => this.get(channelId)?.permissionOverwrites);
|
|
3941
4914
|
}
|
|
3942
4915
|
threads(channelId) {
|
|
3943
4916
|
return new ThreadManager(this.#rest, this.#context, channelId);
|
|
3944
4917
|
}
|
|
3945
|
-
|
|
3946
|
-
return this.
|
|
4918
|
+
fetch(channelId) {
|
|
4919
|
+
return this.fetchOnce(channelId, async () => createChannel(await this.#rest.get(Routes.channel(channelId)), this.#context), (channel) => this.#merge(channel));
|
|
3947
4920
|
}
|
|
3948
4921
|
async resolve(channelId) {
|
|
3949
4922
|
return this.get(channelId) ?? this.fetch(channelId);
|
|
3950
4923
|
}
|
|
3951
4924
|
upsert(data) {
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
4925
|
+
return this.#merge(createChannel(data, this.#context));
|
|
4926
|
+
}
|
|
4927
|
+
#merge(channel) {
|
|
4928
|
+
const existing = this.get(channel.id);
|
|
4929
|
+
if (existing && existing.type === channel.type) {
|
|
3955
4930
|
Object.assign(existing, channel);
|
|
3956
4931
|
return existing;
|
|
3957
4932
|
}
|
|
@@ -3961,6 +4936,37 @@ class ChannelManager extends Manager {
|
|
|
3961
4936
|
update(channel) {
|
|
3962
4937
|
return this.set(channel.id, channel);
|
|
3963
4938
|
}
|
|
4939
|
+
deleteGuildChannels(guildId) {
|
|
4940
|
+
let removed = 0;
|
|
4941
|
+
for (const channel of this.values())
|
|
4942
|
+
if (channel.guildId === guildId && this.delete(channel.id))
|
|
4943
|
+
removed++;
|
|
4944
|
+
return removed;
|
|
4945
|
+
}
|
|
4946
|
+
async endPoll(channelId, messageId) {
|
|
4947
|
+
return this.messages(channelId).upsert(await this.#rest.post(Routes.pollExpire(channelId, messageId)));
|
|
4948
|
+
}
|
|
4949
|
+
async fetchPollVoters(channelId, messageId, answerId, options = {}) {
|
|
4950
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100))
|
|
4951
|
+
throw new RangeError("Poll voter limit must be 1-100.");
|
|
4952
|
+
const params = new URLSearchParams;
|
|
4953
|
+
if (options.after)
|
|
4954
|
+
params.set("after", options.after);
|
|
4955
|
+
if (options.limit !== undefined)
|
|
4956
|
+
params.set("limit", String(options.limit));
|
|
4957
|
+
const suffix = params.toString();
|
|
4958
|
+
const { users } = await this.#rest.get(`${Routes.pollAnswerVoters(channelId, messageId, answerId)}${suffix ? `?${suffix}` : ""}`);
|
|
4959
|
+
return users.map((user) => new User(user));
|
|
4960
|
+
}
|
|
4961
|
+
async sendSoundboardSound(channelId, options) {
|
|
4962
|
+
await this.#rest.post(Routes.sendSoundboardSound(channelId), {
|
|
4963
|
+
sound_id: options.soundId,
|
|
4964
|
+
source_guild_id: options.sourceGuildId
|
|
4965
|
+
});
|
|
4966
|
+
}
|
|
4967
|
+
cachedMessages(channelId) {
|
|
4968
|
+
return this.#messageManagers.get(channelId);
|
|
4969
|
+
}
|
|
3964
4970
|
async create(guildId, options) {
|
|
3965
4971
|
return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
|
|
3966
4972
|
}
|
|
@@ -4004,7 +5010,7 @@ class ChannelManager extends Manager {
|
|
|
4004
5010
|
return this.messages(data.channel_id).upsert(data);
|
|
4005
5011
|
}
|
|
4006
5012
|
async editMessage(channelId, messageId, options) {
|
|
4007
|
-
return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), options));
|
|
5013
|
+
return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options)));
|
|
4008
5014
|
}
|
|
4009
5015
|
async deleteMessage(channelId, messageId) {
|
|
4010
5016
|
await this.#rest.delete(Routes.message(channelId, messageId));
|
|
@@ -4017,15 +5023,37 @@ class ChannelManager extends Manager {
|
|
|
4017
5023
|
return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
|
|
4018
5024
|
}
|
|
4019
5025
|
async bulkDeleteMessages(channelId, messageIds) {
|
|
4020
|
-
const ids = [...messageIds];
|
|
4021
|
-
if (ids.length <
|
|
4022
|
-
throw new RangeError("bulkDelete requires between
|
|
5026
|
+
const ids = [...new Set(messageIds)];
|
|
5027
|
+
if (ids.length < 1 || ids.length > 100)
|
|
5028
|
+
throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
|
|
5029
|
+
if (ids.length === 1)
|
|
5030
|
+
return this.deleteMessage(channelId, ids[0]);
|
|
5031
|
+
const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
|
|
5032
|
+
const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
|
|
5033
|
+
if (tooOld.length)
|
|
5034
|
+
throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
|
|
4023
5035
|
await this.#rest.post(Routes.channelBulkDelete(channelId), {
|
|
4024
5036
|
messages: ids
|
|
4025
5037
|
});
|
|
4026
5038
|
for (const id of ids)
|
|
4027
5039
|
this.messages(channelId).delete(id);
|
|
4028
5040
|
}
|
|
5041
|
+
async* iterateMessages(channelId, options = {}) {
|
|
5042
|
+
let before = options.before;
|
|
5043
|
+
let remaining = options.limit ?? Infinity;
|
|
5044
|
+
while (remaining > 0) {
|
|
5045
|
+
const page = await this.fetchMessages(channelId, {
|
|
5046
|
+
before,
|
|
5047
|
+
limit: Math.min(100, remaining)
|
|
5048
|
+
});
|
|
5049
|
+
for (const message of page)
|
|
5050
|
+
yield message;
|
|
5051
|
+
remaining -= page.length;
|
|
5052
|
+
if (page.length < 100)
|
|
5053
|
+
return;
|
|
5054
|
+
before = page.at(-1).id;
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
4029
5057
|
async addReaction(channelId, messageId, emoji) {
|
|
4030
5058
|
await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
|
|
4031
5059
|
}
|
|
@@ -4121,6 +5149,8 @@ class GatewaySession {
|
|
|
4121
5149
|
return false;
|
|
4122
5150
|
if (!Number.isInteger(sequence))
|
|
4123
5151
|
return false;
|
|
5152
|
+
if (this.#sequence !== null && sequence < this.#sequence)
|
|
5153
|
+
return false;
|
|
4124
5154
|
this.#sequence = sequence;
|
|
4125
5155
|
return true;
|
|
4126
5156
|
}
|
|
@@ -4219,8 +5249,11 @@ class GatewayHeartbeat {
|
|
|
4219
5249
|
this.#clearBeatTimers();
|
|
4220
5250
|
this.#interval = interval;
|
|
4221
5251
|
this.#acknowledged = true;
|
|
4222
|
-
this.#initialTimer = setTimeout(() =>
|
|
4223
|
-
|
|
5252
|
+
this.#initialTimer = setTimeout(() => {
|
|
5253
|
+
this.#initialTimer = undefined;
|
|
5254
|
+
this.sendHeartbeat();
|
|
5255
|
+
this.#timer = setInterval(() => this.sendHeartbeat(), interval);
|
|
5256
|
+
}, Math.random() * interval);
|
|
4224
5257
|
}
|
|
4225
5258
|
stop() {
|
|
4226
5259
|
this.#clearBeatTimers();
|
|
@@ -4246,6 +5279,8 @@ class GatewayHeartbeat {
|
|
|
4246
5279
|
}, this.#options.ackTimeout);
|
|
4247
5280
|
}
|
|
4248
5281
|
acknowledge() {
|
|
5282
|
+
if (this.#acknowledged)
|
|
5283
|
+
return;
|
|
4249
5284
|
this.#acknowledged = true;
|
|
4250
5285
|
this.#latency = this.#now() - this.#sentAt;
|
|
4251
5286
|
this.#clearAckTimer();
|
|
@@ -4826,6 +5861,7 @@ class SendBudget {
|
|
|
4826
5861
|
}
|
|
4827
5862
|
|
|
4828
5863
|
// packages/ws/src/index.ts
|
|
5864
|
+
var RESUMABLE_CLOSE_CODE = 4900;
|
|
4829
5865
|
var DEFAULT_GATEWAY_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
4830
5866
|
|
|
4831
5867
|
class Gateway {
|
|
@@ -4911,7 +5947,7 @@ class Gateway {
|
|
|
4911
5947
|
} else {
|
|
4912
5948
|
this.#emitError(new GatewayError(`Gateway heartbeat acknowledgement timed out after ${timeout.elapsedMs}ms.`));
|
|
4913
5949
|
}
|
|
4914
|
-
this.#transport.close(
|
|
5950
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, timeout.type === "zombie" ? "Zombie Gateway connection" : "Heartbeat timeout");
|
|
4915
5951
|
}
|
|
4916
5952
|
connect(url = DEFAULT_GATEWAY_URL) {
|
|
4917
5953
|
if (this.state === "CLOSED" /* Closed */)
|
|
@@ -5047,7 +6083,7 @@ class Gateway {
|
|
|
5047
6083
|
this.#emit("heartbeatAck", action.data);
|
|
5048
6084
|
return;
|
|
5049
6085
|
case "reconnect":
|
|
5050
|
-
this.#transport.close(
|
|
6086
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, "Server requested reconnect");
|
|
5051
6087
|
return;
|
|
5052
6088
|
case "invalid-session": {
|
|
5053
6089
|
if (!action.resumable)
|
|
@@ -5241,6 +6277,7 @@ class Client extends EventEmitter2 {
|
|
|
5241
6277
|
channels;
|
|
5242
6278
|
stageInstances;
|
|
5243
6279
|
application;
|
|
6280
|
+
monetization;
|
|
5244
6281
|
get ws() {
|
|
5245
6282
|
return this.#gateway;
|
|
5246
6283
|
}
|
|
@@ -5272,6 +6309,7 @@ class Client extends EventEmitter2 {
|
|
|
5272
6309
|
return this.#gateway.requestGuildMembers(data);
|
|
5273
6310
|
}
|
|
5274
6311
|
#gateway;
|
|
6312
|
+
#cache;
|
|
5275
6313
|
#resourceContext;
|
|
5276
6314
|
constructor(options) {
|
|
5277
6315
|
super();
|
|
@@ -5279,9 +6317,18 @@ class Client extends EventEmitter2 {
|
|
|
5279
6317
|
if (!options.token?.trim())
|
|
5280
6318
|
throw new TypeError("Client token is required.");
|
|
5281
6319
|
this.rest = new REST({ token: options.token, ...options.rest });
|
|
6320
|
+
this.#cache = {
|
|
6321
|
+
users: true,
|
|
6322
|
+
members: true,
|
|
6323
|
+
roles: true,
|
|
6324
|
+
emojis: true,
|
|
6325
|
+
...options.cache
|
|
6326
|
+
};
|
|
5282
6327
|
this.users = new UserManager(this.rest);
|
|
5283
6328
|
this.guilds = new GuildManager(this.rest);
|
|
5284
|
-
this.channels = new ChannelManager(this.rest
|
|
6329
|
+
this.channels = new ChannelManager(this.rest, {
|
|
6330
|
+
messageCache: options.messageCache
|
|
6331
|
+
});
|
|
5285
6332
|
this.stageInstances = new StageInstanceManager(this.rest);
|
|
5286
6333
|
const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
|
|
5287
6334
|
this.application = { commands: placeholderAppCommands };
|
|
@@ -5297,8 +6344,32 @@ class Client extends EventEmitter2 {
|
|
|
5297
6344
|
removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
|
|
5298
6345
|
removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
|
|
5299
6346
|
pinMessage: (channelId, messageId) => this.channels.pinMessage(channelId, messageId),
|
|
5300
|
-
unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId)
|
|
6347
|
+
unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId),
|
|
6348
|
+
collectInteractions: (options) => this.createCollector("interactionCreate" /* InteractionCreate */, options),
|
|
6349
|
+
memberPermissions: (guildId, memberId, roleIds, channelId) => this.#memberPermissions(guildId, memberId, roleIds, channelId),
|
|
6350
|
+
kickMember: (guildId, userId, reason) => this.guilds.members(guildId).kick(userId, reason),
|
|
6351
|
+
banMember: (guildId, userId, options) => this.guilds.members(guildId).ban(userId, options),
|
|
6352
|
+
editMember: (guildId, userId, options, reason) => this.guilds.members(guildId).edit(userId, options, reason),
|
|
6353
|
+
addMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).addRole(userId, roleId, reason),
|
|
6354
|
+
removeMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).removeRole(userId, roleId, reason),
|
|
6355
|
+
editPermissionOverwrite: async (channelId, targetId, changes, options) => {
|
|
6356
|
+
const bits = { allow: 0n, deny: 0n, inherit: 0n };
|
|
6357
|
+
for (const [name, value] of Object.entries(changes)) {
|
|
6358
|
+
if (!/^[A-Za-z]+$/.test(name))
|
|
6359
|
+
throw new TypeError(`Unknown permission: ${name}`);
|
|
6360
|
+
let bit;
|
|
6361
|
+
try {
|
|
6362
|
+
bit = new PermissionSet(name).bitfield;
|
|
6363
|
+
} catch {
|
|
6364
|
+
throw new TypeError(`Unknown permission: ${name}`);
|
|
6365
|
+
}
|
|
6366
|
+
const key = value === true ? "allow" : value === false ? "deny" : "inherit";
|
|
6367
|
+
bits[key] |= bit;
|
|
6368
|
+
}
|
|
6369
|
+
return this.channels.permissionOverwrites(channelId).update(targetId, bits, options);
|
|
6370
|
+
}
|
|
5301
6371
|
};
|
|
6372
|
+
this.guilds.attachContext(this.#resourceContext);
|
|
5302
6373
|
this.#gateway = new Gateway({
|
|
5303
6374
|
token: options.token,
|
|
5304
6375
|
intents: options.intents,
|
|
@@ -5312,6 +6383,8 @@ class Client extends EventEmitter2 {
|
|
|
5312
6383
|
this.state = "ready";
|
|
5313
6384
|
const appId = ready.application?.id ?? this.user.id;
|
|
5314
6385
|
this.application.commands = new ApplicationCommandManager(this.rest, appId);
|
|
6386
|
+
if (this.monetization?.applicationId !== appId)
|
|
6387
|
+
this.monetization = new MonetizationManager(this.rest, appId);
|
|
5315
6388
|
this.emit("ready" /* Ready */, this.user);
|
|
5316
6389
|
});
|
|
5317
6390
|
this.#gateway.on("RESUMED", () => {
|
|
@@ -5328,19 +6401,46 @@ class Client extends EventEmitter2 {
|
|
|
5328
6401
|
this.emit("close" /* Close */, data);
|
|
5329
6402
|
});
|
|
5330
6403
|
this.#gateway.on("MESSAGE_CREATE", (data) => {
|
|
5331
|
-
const
|
|
5332
|
-
|
|
5333
|
-
this
|
|
5334
|
-
|
|
6404
|
+
const payload = data;
|
|
6405
|
+
const message = new Message(payload, this.#resourceContext);
|
|
6406
|
+
this.#observeMessage(message);
|
|
6407
|
+
if (payload.member && payload.guild_id && this.guilds.has(payload.guild_id))
|
|
6408
|
+
this.#upsertMember(payload.guild_id, {
|
|
6409
|
+
...payload.member,
|
|
6410
|
+
user: payload.member.user ?? payload.author
|
|
6411
|
+
});
|
|
6412
|
+
const cached = this.options.messageCache ? this.channels.messages(message.channelId).upsert(data) : message;
|
|
6413
|
+
this.emit("messageCreate" /* MessageCreate */, cached);
|
|
5335
6414
|
});
|
|
5336
6415
|
this.#gateway.on("MESSAGE_UPDATE", (data) => {
|
|
5337
6416
|
const message = new Message(data, this.#resourceContext);
|
|
5338
|
-
this
|
|
5339
|
-
this.
|
|
5340
|
-
|
|
6417
|
+
this.#observeMessage(message);
|
|
6418
|
+
const messages = this.channels.cachedMessages(message.channelId);
|
|
6419
|
+
const previous = messages?.cache.peek(message.id);
|
|
6420
|
+
if (previous)
|
|
6421
|
+
messages.cache.set(message.id, message);
|
|
6422
|
+
this.emit("messageUpdate" /* MessageUpdate */, message, previous);
|
|
6423
|
+
});
|
|
6424
|
+
this.#gateway.on("MESSAGE_DELETE", (data) => {
|
|
6425
|
+
const payload = data;
|
|
6426
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
6427
|
+
const removed = messages?.cache.peek(payload.id);
|
|
6428
|
+
messages?.delete(payload.id);
|
|
6429
|
+
this.emit("messageDelete" /* MessageDelete */, payload, removed);
|
|
6430
|
+
});
|
|
6431
|
+
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => {
|
|
6432
|
+
const payload = data;
|
|
6433
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
6434
|
+
const removed = [];
|
|
6435
|
+
if (messages)
|
|
6436
|
+
for (const id of payload.ids) {
|
|
6437
|
+
const message = messages.cache.peek(id);
|
|
6438
|
+
if (message)
|
|
6439
|
+
removed.push(message);
|
|
6440
|
+
messages.delete(id);
|
|
6441
|
+
}
|
|
6442
|
+
this.emit("messageDeleteBulk" /* MessageDeleteBulk */, payload, removed);
|
|
5341
6443
|
});
|
|
5342
|
-
this.#gateway.on("MESSAGE_DELETE", (data) => this.emit("messageDelete" /* MessageDelete */, data));
|
|
5343
|
-
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => this.emit("messageDeleteBulk" /* MessageDeleteBulk */, data));
|
|
5344
6444
|
this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
|
|
5345
6445
|
this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
|
|
5346
6446
|
this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
|
|
@@ -5354,20 +6454,27 @@ class Client extends EventEmitter2 {
|
|
|
5354
6454
|
return;
|
|
5355
6455
|
}
|
|
5356
6456
|
const wasCached = this.guilds.has(payload.id);
|
|
5357
|
-
|
|
5358
|
-
|
|
6457
|
+
this.guilds.patch(payload);
|
|
6458
|
+
for (const role of payload.roles ?? [])
|
|
6459
|
+
this.#upsertRole(payload.id, role);
|
|
6460
|
+
if (this.#cache.emojis) {
|
|
6461
|
+
const emojis = this.guilds.emojis(payload.id);
|
|
6462
|
+
for (const emoji of payload.emojis ?? [])
|
|
6463
|
+
emojis.upsert(emoji);
|
|
6464
|
+
}
|
|
5359
6465
|
for (const member of payload.members ?? [])
|
|
5360
|
-
this
|
|
6466
|
+
this.#upsertMember(payload.id, member);
|
|
6467
|
+
for (const state of payload.voice_states ?? [])
|
|
6468
|
+
this.#storeVoiceState(payload.id, state);
|
|
5361
6469
|
for (const channelData of [
|
|
5362
6470
|
...payload.channels ?? [],
|
|
5363
6471
|
...payload.threads ?? []
|
|
5364
6472
|
])
|
|
5365
|
-
this.channels.
|
|
6473
|
+
this.channels.upsert({ ...channelData, guild_id: payload.id });
|
|
5366
6474
|
this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
|
|
5367
6475
|
});
|
|
5368
6476
|
this.#gateway.on("GUILD_UPDATE", (data) => {
|
|
5369
|
-
|
|
5370
|
-
this.guilds.update(guild);
|
|
6477
|
+
this.guilds.patch(data);
|
|
5371
6478
|
this.emit("guildUpdate" /* GuildUpdate */, data);
|
|
5372
6479
|
});
|
|
5373
6480
|
this.#gateway.on("GUILD_DELETE", (data) => {
|
|
@@ -5377,45 +6484,158 @@ class Client extends EventEmitter2 {
|
|
|
5377
6484
|
return;
|
|
5378
6485
|
}
|
|
5379
6486
|
this.guilds.delete(payload.id);
|
|
6487
|
+
this.channels.deleteGuildChannels(payload.id);
|
|
5380
6488
|
this.emit("guildDelete" /* GuildDelete */, payload);
|
|
5381
6489
|
});
|
|
5382
6490
|
this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
|
|
5383
6491
|
const member = data;
|
|
5384
|
-
this
|
|
6492
|
+
this.#upsertMember(member.guild_id, member);
|
|
5385
6493
|
this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
|
|
5386
6494
|
});
|
|
5387
6495
|
this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
|
|
5388
6496
|
const member = data;
|
|
5389
|
-
this
|
|
6497
|
+
this.#upsertMember(member.guild_id, member);
|
|
5390
6498
|
this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
|
|
5391
6499
|
});
|
|
5392
|
-
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) =>
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
this.#gateway.on("
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
6500
|
+
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
|
|
6501
|
+
const member = data;
|
|
6502
|
+
this.guilds.members(member.guild_id).delete(member.user.id);
|
|
6503
|
+
this.emit("guildMemberRemove" /* GuildMemberRemove */, member);
|
|
6504
|
+
});
|
|
6505
|
+
this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => {
|
|
6506
|
+
const chunk = data;
|
|
6507
|
+
for (const member of chunk.members)
|
|
6508
|
+
this.#upsertMember(chunk.guild_id, member);
|
|
6509
|
+
this.emit("guildMembersChunk" /* GuildMembersChunk */, chunk);
|
|
6510
|
+
});
|
|
6511
|
+
this.#gateway.on("GUILD_BAN_ADD", (data) => {
|
|
6512
|
+
const ban = data;
|
|
6513
|
+
const bans = this.guilds.bans(ban.guild_id);
|
|
6514
|
+
bans.set(ban.user.id, {
|
|
6515
|
+
reason: bans.get(ban.user.id)?.reason ?? null,
|
|
6516
|
+
user: ban.user
|
|
6517
|
+
});
|
|
6518
|
+
this.guilds.members(ban.guild_id).delete(ban.user.id);
|
|
6519
|
+
this.emit("guildBanAdd" /* GuildBanAdd */, ban);
|
|
6520
|
+
});
|
|
6521
|
+
this.#gateway.on("GUILD_BAN_REMOVE", (data) => {
|
|
6522
|
+
const ban = data;
|
|
6523
|
+
this.guilds.bans(ban.guild_id).delete(ban.user.id);
|
|
6524
|
+
this.emit("guildBanRemove" /* GuildBanRemove */, ban);
|
|
6525
|
+
});
|
|
6526
|
+
this.#gateway.on("GUILD_ROLE_CREATE", (data) => {
|
|
6527
|
+
const event = data;
|
|
6528
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
6529
|
+
this.emit("guildRoleCreate" /* GuildRoleCreate */, event);
|
|
6530
|
+
});
|
|
6531
|
+
this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
|
|
6532
|
+
const event = data;
|
|
6533
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
6534
|
+
this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
|
|
6535
|
+
});
|
|
6536
|
+
this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
|
|
6537
|
+
const event = data;
|
|
6538
|
+
this.guilds.roles(event.guild_id).delete(event.role_id);
|
|
6539
|
+
this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
|
|
6540
|
+
});
|
|
6541
|
+
this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
|
|
6542
|
+
const event = data;
|
|
6543
|
+
if (this.#cache.emojis) {
|
|
6544
|
+
const emojis = this.guilds.emojis(event.guild_id);
|
|
6545
|
+
const current = new Set(event.emojis.map((emoji) => emoji.id));
|
|
6546
|
+
for (const id of [...emojis.cache.keys()])
|
|
6547
|
+
if (!current.has(id))
|
|
6548
|
+
emojis.delete(id);
|
|
6549
|
+
for (const emoji of event.emojis)
|
|
6550
|
+
emojis.upsert(emoji);
|
|
6551
|
+
}
|
|
6552
|
+
this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
|
|
6553
|
+
});
|
|
6554
|
+
this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
|
|
6555
|
+
const event = data;
|
|
6556
|
+
this.guilds.stickers(event.guild_id).sync(event.stickers);
|
|
6557
|
+
this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
|
|
6558
|
+
});
|
|
6559
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
|
|
6560
|
+
const sound = data;
|
|
6561
|
+
if (sound.guild_id)
|
|
6562
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
6563
|
+
this.emit("soundboardSoundCreate" /* SoundboardSoundCreate */, sound);
|
|
6564
|
+
});
|
|
6565
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_UPDATE", (data) => {
|
|
6566
|
+
const sound = data;
|
|
6567
|
+
if (sound.guild_id)
|
|
6568
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
6569
|
+
this.emit("soundboardSoundUpdate" /* SoundboardSoundUpdate */, sound);
|
|
6570
|
+
});
|
|
6571
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_DELETE", (data) => {
|
|
6572
|
+
const event = data;
|
|
6573
|
+
this.guilds.soundboard(event.guild_id).delete(event.sound_id);
|
|
6574
|
+
this.emit("soundboardSoundDelete" /* SoundboardSoundDelete */, event);
|
|
6575
|
+
});
|
|
6576
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUNDS_UPDATE", (data) => {
|
|
6577
|
+
const event = data;
|
|
6578
|
+
const sounds = this.guilds.soundboard(event.guild_id);
|
|
6579
|
+
sounds.clear();
|
|
6580
|
+
for (const sound of event.soundboard_sounds)
|
|
6581
|
+
sounds.set(sound.sound_id, sound);
|
|
6582
|
+
this.emit("soundboardSoundsUpdate" /* SoundboardSoundsUpdate */, event);
|
|
6583
|
+
});
|
|
6584
|
+
this.#gateway.on("ENTITLEMENT_CREATE", (data) => {
|
|
6585
|
+
const entitlement = data;
|
|
6586
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
6587
|
+
this.emit("entitlementCreate" /* EntitlementCreate */, entitlement);
|
|
6588
|
+
});
|
|
6589
|
+
this.#gateway.on("ENTITLEMENT_UPDATE", (data) => {
|
|
6590
|
+
const entitlement = data;
|
|
6591
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
6592
|
+
this.emit("entitlementUpdate" /* EntitlementUpdate */, entitlement);
|
|
6593
|
+
});
|
|
6594
|
+
this.#gateway.on("ENTITLEMENT_DELETE", (data) => {
|
|
6595
|
+
const entitlement = data;
|
|
6596
|
+
this.monetization?.delete(entitlement.id);
|
|
6597
|
+
this.emit("entitlementDelete" /* EntitlementDelete */, entitlement);
|
|
6598
|
+
});
|
|
5401
6599
|
this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
|
|
5402
|
-
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) =>
|
|
5403
|
-
|
|
5404
|
-
|
|
6600
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => {
|
|
6601
|
+
const event = data;
|
|
6602
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
6603
|
+
this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, event);
|
|
6604
|
+
});
|
|
6605
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => {
|
|
6606
|
+
const event = data;
|
|
6607
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
6608
|
+
this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, event);
|
|
6609
|
+
});
|
|
6610
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => {
|
|
6611
|
+
const event = data;
|
|
6612
|
+
this.guilds.scheduledEvents(event.guild_id).delete(event.id);
|
|
6613
|
+
this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, event);
|
|
6614
|
+
});
|
|
5405
6615
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
|
|
5406
6616
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_REMOVE", (data) => this.emit("guildScheduledEventUserRemove" /* GuildScheduledEventUserRemove */, data));
|
|
5407
|
-
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) =>
|
|
5408
|
-
|
|
5409
|
-
|
|
6617
|
+
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => {
|
|
6618
|
+
const rule = data;
|
|
6619
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
6620
|
+
this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, rule);
|
|
6621
|
+
});
|
|
6622
|
+
this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => {
|
|
6623
|
+
const rule = data;
|
|
6624
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
6625
|
+
this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, rule);
|
|
6626
|
+
});
|
|
6627
|
+
this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => {
|
|
6628
|
+
const rule = data;
|
|
6629
|
+
this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);
|
|
6630
|
+
this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
|
|
6631
|
+
});
|
|
5410
6632
|
this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
|
|
5411
6633
|
this.#gateway.on("CHANNEL_CREATE", (data) => {
|
|
5412
|
-
const channel =
|
|
5413
|
-
this.channels.update(channel);
|
|
6634
|
+
const channel = this.channels.upsert(data);
|
|
5414
6635
|
this.emit("channelCreate" /* ChannelCreate */, channel);
|
|
5415
6636
|
});
|
|
5416
6637
|
this.#gateway.on("CHANNEL_UPDATE", (data) => {
|
|
5417
|
-
const channel =
|
|
5418
|
-
this.channels.update(channel);
|
|
6638
|
+
const channel = this.channels.upsert(data);
|
|
5419
6639
|
this.emit("channelUpdate" /* ChannelUpdate */, channel);
|
|
5420
6640
|
});
|
|
5421
6641
|
this.#gateway.on("CHANNEL_DELETE", (data) => {
|
|
@@ -5425,13 +6645,11 @@ class Client extends EventEmitter2 {
|
|
|
5425
6645
|
});
|
|
5426
6646
|
this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
|
|
5427
6647
|
this.#gateway.on("THREAD_CREATE", (data) => {
|
|
5428
|
-
const channel =
|
|
5429
|
-
this.channels.update(channel);
|
|
6648
|
+
const channel = this.channels.upsert(data);
|
|
5430
6649
|
this.emit("threadCreate" /* ThreadCreate */, channel);
|
|
5431
6650
|
});
|
|
5432
6651
|
this.#gateway.on("THREAD_UPDATE", (data) => {
|
|
5433
|
-
const channel =
|
|
5434
|
-
this.channels.update(channel);
|
|
6652
|
+
const channel = this.channels.upsert(data);
|
|
5435
6653
|
this.emit("threadUpdate" /* ThreadUpdate */, channel);
|
|
5436
6654
|
});
|
|
5437
6655
|
this.#gateway.on("THREAD_DELETE", (data) => {
|
|
@@ -5439,16 +6657,48 @@ class Client extends EventEmitter2 {
|
|
|
5439
6657
|
this.channels.delete(payload.id);
|
|
5440
6658
|
this.emit("threadDelete" /* ThreadDelete */, payload);
|
|
5441
6659
|
});
|
|
5442
|
-
this.#gateway.on("THREAD_LIST_SYNC", (data) =>
|
|
6660
|
+
this.#gateway.on("THREAD_LIST_SYNC", (data) => {
|
|
6661
|
+
const sync = data;
|
|
6662
|
+
for (const thread of sync.threads)
|
|
6663
|
+
this.channels.upsert({ ...thread, guild_id: sync.guild_id });
|
|
6664
|
+
this.emit("threadListSync" /* ThreadListSync */, sync);
|
|
6665
|
+
});
|
|
5443
6666
|
this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
|
|
5444
6667
|
this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
|
|
5445
|
-
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) =>
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
6668
|
+
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => {
|
|
6669
|
+
const stage = data;
|
|
6670
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
6671
|
+
this.emit("stageInstanceCreate" /* StageInstanceCreate */, stage);
|
|
6672
|
+
});
|
|
6673
|
+
this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => {
|
|
6674
|
+
const stage = data;
|
|
6675
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
6676
|
+
this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, stage);
|
|
6677
|
+
});
|
|
6678
|
+
this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => {
|
|
6679
|
+
const stage = data;
|
|
6680
|
+
this.stageInstances.delete(stage.channel_id);
|
|
6681
|
+
this.emit("stageInstanceDelete" /* StageInstanceDelete */, stage);
|
|
6682
|
+
});
|
|
6683
|
+
this.#gateway.on("INVITE_CREATE", (data) => {
|
|
6684
|
+
const invite = data;
|
|
6685
|
+
if (invite.guild_id)
|
|
6686
|
+
this.guilds.invites(invite.guild_id).set(invite.code, invite);
|
|
6687
|
+
this.emit("inviteCreate" /* InviteCreate */, invite);
|
|
6688
|
+
});
|
|
6689
|
+
this.#gateway.on("INVITE_DELETE", (data) => {
|
|
6690
|
+
const invite = data;
|
|
6691
|
+
if (invite.guild_id)
|
|
6692
|
+
this.guilds.invites(invite.guild_id).delete(invite.code);
|
|
6693
|
+
this.emit("inviteDelete" /* InviteDelete */, invite);
|
|
6694
|
+
});
|
|
5450
6695
|
this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
|
|
5451
|
-
this.#gateway.on("VOICE_STATE_UPDATE", (data) =>
|
|
6696
|
+
this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
|
|
6697
|
+
const state = data;
|
|
6698
|
+
if (state.guild_id)
|
|
6699
|
+
this.#storeVoiceState(state.guild_id, state);
|
|
6700
|
+
this.emit("voiceStateUpdate" /* VoiceStateUpdate */, state);
|
|
6701
|
+
});
|
|
5452
6702
|
this.#gateway.on("VOICE_SERVER_UPDATE", (data) => this.emit("voiceServerUpdate" /* VoiceServerUpdate */, data));
|
|
5453
6703
|
this.#gateway.on("PRESENCE_UPDATE", (data) => this.emit("presenceUpdate" /* PresenceUpdate */, data));
|
|
5454
6704
|
this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
|
|
@@ -5456,6 +6706,103 @@ class Client extends EventEmitter2 {
|
|
|
5456
6706
|
this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
|
|
5457
6707
|
this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
|
|
5458
6708
|
}
|
|
6709
|
+
#observeMessage(message) {
|
|
6710
|
+
if (!this.channels.has(message.channelId))
|
|
6711
|
+
this.channels.set(message.channelId, message.channel);
|
|
6712
|
+
if (this.#cache.users)
|
|
6713
|
+
this.#merge(this.users, message.author.id, message.author);
|
|
6714
|
+
}
|
|
6715
|
+
#upsertMember(guildId, data) {
|
|
6716
|
+
const member = new GuildMember({ ...data, guild_id: guildId }, this.#resourceContext);
|
|
6717
|
+
if (this.#cache.users)
|
|
6718
|
+
this.#merge(this.users, member.user.id, member.user);
|
|
6719
|
+
if (!this.#cache.members)
|
|
6720
|
+
return member;
|
|
6721
|
+
return this.#merge(this.guilds.members(guildId), member.user.id, member);
|
|
6722
|
+
}
|
|
6723
|
+
#storeVoiceState(guildId, state) {
|
|
6724
|
+
const states = this.guilds.voiceStates(guildId);
|
|
6725
|
+
if (state.channel_id)
|
|
6726
|
+
states.set(state.user_id, state);
|
|
6727
|
+
else
|
|
6728
|
+
states.delete(state.user_id);
|
|
6729
|
+
}
|
|
6730
|
+
#upsertRole(guildId, data) {
|
|
6731
|
+
if (!this.#cache.roles)
|
|
6732
|
+
return new Role(data);
|
|
6733
|
+
return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
|
|
6734
|
+
}
|
|
6735
|
+
#merge(manager, id, next) {
|
|
6736
|
+
const existing = manager.get(id);
|
|
6737
|
+
if (!existing) {
|
|
6738
|
+
manager.set(id, next);
|
|
6739
|
+
return next;
|
|
6740
|
+
}
|
|
6741
|
+
for (const [key, value] of Object.entries(next))
|
|
6742
|
+
if (value !== undefined)
|
|
6743
|
+
existing[key] = value;
|
|
6744
|
+
return existing;
|
|
6745
|
+
}
|
|
6746
|
+
createCollector(event, options = {}) {
|
|
6747
|
+
const collector = new Collector(options);
|
|
6748
|
+
let order = 0;
|
|
6749
|
+
const listener = (...args) => {
|
|
6750
|
+
const item = args[0];
|
|
6751
|
+
const id = item?.id;
|
|
6752
|
+
const key = options.key?.(item) ?? (typeof id === "string" ? id : String(order++));
|
|
6753
|
+
collector.handle(key, item).catch((error) => this.emit("error" /* Error */, error instanceof Error ? error : new Error(String(error))));
|
|
6754
|
+
};
|
|
6755
|
+
this.on(event, listener);
|
|
6756
|
+
collector.onDispose(() => this.off(event, listener));
|
|
6757
|
+
return collector;
|
|
6758
|
+
}
|
|
6759
|
+
get resourceContext() {
|
|
6760
|
+
return this.#resourceContext;
|
|
6761
|
+
}
|
|
6762
|
+
#memberPermissions(guildId, memberId, roleIds, channelId) {
|
|
6763
|
+
const guild = this.guilds.get(guildId);
|
|
6764
|
+
if (!guild)
|
|
6765
|
+
return null;
|
|
6766
|
+
let channel = channelId ? this.channels.get(channelId) : undefined;
|
|
6767
|
+
if (channelId) {
|
|
6768
|
+
if (channel?.isThread())
|
|
6769
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
6770
|
+
if (!channel || channel.guildId !== guildId)
|
|
6771
|
+
return null;
|
|
6772
|
+
}
|
|
6773
|
+
return computePermissions({
|
|
6774
|
+
guildId,
|
|
6775
|
+
ownerId: guild.ownerId,
|
|
6776
|
+
memberId,
|
|
6777
|
+
memberRoleIds: [...roleIds],
|
|
6778
|
+
roles: this.guilds.roles(guildId).values(),
|
|
6779
|
+
overwrites: channel?.permissionOverwrites
|
|
6780
|
+
});
|
|
6781
|
+
}
|
|
6782
|
+
permissionsFor(memberId, guildOrChannelId) {
|
|
6783
|
+
let channel = this.channels.get(guildOrChannelId);
|
|
6784
|
+
if (channel?.isThread()) {
|
|
6785
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
6786
|
+
if (!channel)
|
|
6787
|
+
return null;
|
|
6788
|
+
}
|
|
6789
|
+
const guildId = channel?.guildId ?? guildOrChannelId;
|
|
6790
|
+
const guild = this.guilds.get(guildId);
|
|
6791
|
+
const member = this.guilds.members(guildId).get(memberId);
|
|
6792
|
+
if (!guild || !member)
|
|
6793
|
+
return null;
|
|
6794
|
+
return computePermissions({
|
|
6795
|
+
guildId,
|
|
6796
|
+
ownerId: guild.ownerId,
|
|
6797
|
+
memberId,
|
|
6798
|
+
memberRoleIds: member.roleIds,
|
|
6799
|
+
roles: this.guilds.roles(guildId).values(),
|
|
6800
|
+
overwrites: channel?.permissionOverwrites
|
|
6801
|
+
});
|
|
6802
|
+
}
|
|
6803
|
+
fetchDefaultSoundboardSounds() {
|
|
6804
|
+
return this.rest.get(Routes.soundboardDefaultSounds());
|
|
6805
|
+
}
|
|
5459
6806
|
async login(token) {
|
|
5460
6807
|
if (this.state === "destroyed")
|
|
5461
6808
|
throw new Error("Cannot login a destroyed client.");
|
|
@@ -5475,12 +6822,21 @@ class Client extends EventEmitter2 {
|
|
|
5475
6822
|
this.#gateway.close();
|
|
5476
6823
|
}
|
|
5477
6824
|
postInteractionResponse(id, token, response) {
|
|
5478
|
-
|
|
6825
|
+
const json = response.toJSON();
|
|
6826
|
+
const upload = json.data ? toRequest(json.data) : undefined;
|
|
6827
|
+
if (upload && typeof upload === "object" && "files" in upload) {
|
|
6828
|
+
const { body, files } = upload;
|
|
6829
|
+
return this.rest.post(Routes.interactionCallback(id, token), {
|
|
6830
|
+
body: { ...json, data: body },
|
|
6831
|
+
files
|
|
6832
|
+
});
|
|
6833
|
+
}
|
|
6834
|
+
return this.rest.post(Routes.interactionCallback(id, token), json);
|
|
5479
6835
|
}
|
|
5480
6836
|
editInteractionReply(token, data) {
|
|
5481
6837
|
if (!this.user)
|
|
5482
6838
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
5483
|
-
return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), data);
|
|
6839
|
+
return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data));
|
|
5484
6840
|
}
|
|
5485
6841
|
deleteInteractionReply(token) {
|
|
5486
6842
|
if (!this.user)
|
|
@@ -5490,7 +6846,15 @@ class Client extends EventEmitter2 {
|
|
|
5490
6846
|
followUpInteraction(token, data) {
|
|
5491
6847
|
if (!this.user)
|
|
5492
6848
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
5493
|
-
return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);
|
|
6849
|
+
return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data));
|
|
6850
|
+
}
|
|
6851
|
+
interactionWebhookMessage(method, applicationId, token, messageId, data) {
|
|
6852
|
+
const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
|
|
6853
|
+
if (method === "GET")
|
|
6854
|
+
return this.rest.get(path);
|
|
6855
|
+
if (method === "PATCH")
|
|
6856
|
+
return this.rest.patch(path, data);
|
|
6857
|
+
return this.rest.delete(path);
|
|
5494
6858
|
}
|
|
5495
6859
|
fetchWebhook(id, token) {
|
|
5496
6860
|
return this.rest.get(token ? `/webhooks/${id}/${token}` : `/webhooks/${id}`);
|
|
@@ -5647,6 +7011,21 @@ class HandlerRegistry {
|
|
|
5647
7011
|
return this.dispatch(event, ...args);
|
|
5648
7012
|
}
|
|
5649
7013
|
}
|
|
7014
|
+
// packages/sharding/package.json
|
|
7015
|
+
var package_default2 = {
|
|
7016
|
+
name: "@lunibee/sharding",
|
|
7017
|
+
version: "0.2.1",
|
|
7018
|
+
type: "module",
|
|
7019
|
+
module: "./src/index.ts",
|
|
7020
|
+
types: "./src/index.ts",
|
|
7021
|
+
exports: {
|
|
7022
|
+
".": "./src/index.ts"
|
|
7023
|
+
},
|
|
7024
|
+
dependencies: {
|
|
7025
|
+
"@lunibee/ws": "workspace:*"
|
|
7026
|
+
}
|
|
7027
|
+
};
|
|
7028
|
+
|
|
5650
7029
|
// packages/sharding/src/bus.ts
|
|
5651
7030
|
var REPLY_TYPE = "__lunibee:reply";
|
|
5652
7031
|
|
|
@@ -5824,7 +7203,7 @@ class ClusterManager {
|
|
|
5824
7203
|
const response = await fetch("https://discord.com/api/v10/gateway/bot", {
|
|
5825
7204
|
headers: {
|
|
5826
7205
|
Authorization: `Bot ${this.#options.token}`,
|
|
5827
|
-
"User-Agent":
|
|
7206
|
+
"User-Agent": `Lunibee/${package_default2.version}`
|
|
5828
7207
|
}
|
|
5829
7208
|
});
|
|
5830
7209
|
if (!response.ok) {
|
|
@@ -5975,6 +7354,34 @@ class ClusterManager {
|
|
|
5975
7354
|
|
|
5976
7355
|
// packages/sharding/src/index.ts
|
|
5977
7356
|
var sleep3 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7357
|
+
function needsConnection(gateway) {
|
|
7358
|
+
return gateway.state === "CONNECT" /* Connect */ || gateway.state === "RECONNECT" /* Reconnect */ || gateway.state === "CLOSED" /* Closed */;
|
|
7359
|
+
}
|
|
7360
|
+
var HANDSHAKE_SENT = new Set([
|
|
7361
|
+
"IDENTIFY" /* Identify */,
|
|
7362
|
+
"RESUME" /* Resume */,
|
|
7363
|
+
"READY" /* Ready */,
|
|
7364
|
+
"DISPATCH" /* Dispatch */,
|
|
7365
|
+
"HEARTBEAT" /* Heartbeat */,
|
|
7366
|
+
"CLOSED" /* Closed */
|
|
7367
|
+
]);
|
|
7368
|
+
function handshakeSent(gateway, timeout) {
|
|
7369
|
+
if (HANDSHAKE_SENT.has(gateway.state))
|
|
7370
|
+
return Promise.resolve();
|
|
7371
|
+
return new Promise((resolve) => {
|
|
7372
|
+
const done = () => {
|
|
7373
|
+
clearTimeout(timer);
|
|
7374
|
+
gateway.off("stateChange", onState);
|
|
7375
|
+
resolve();
|
|
7376
|
+
};
|
|
7377
|
+
const onState = (change) => {
|
|
7378
|
+
if (HANDSHAKE_SENT.has(change.next))
|
|
7379
|
+
done();
|
|
7380
|
+
};
|
|
7381
|
+
const timer = setTimeout(done, timeout);
|
|
7382
|
+
gateway.on("stateChange", onState);
|
|
7383
|
+
});
|
|
7384
|
+
}
|
|
5978
7385
|
|
|
5979
7386
|
class ShardManager {
|
|
5980
7387
|
static IDENTIFY_INTERVAL = 5000;
|
|
@@ -5987,6 +7394,7 @@ class ShardManager {
|
|
|
5987
7394
|
#destroyed = false;
|
|
5988
7395
|
#auto;
|
|
5989
7396
|
#autoScaleTimer;
|
|
7397
|
+
#gatewayInfo;
|
|
5990
7398
|
constructor(options) {
|
|
5991
7399
|
if (!options.token?.trim())
|
|
5992
7400
|
throw new TypeError("A Discord bot token is required.");
|
|
@@ -5999,6 +7407,10 @@ class ShardManager {
|
|
|
5999
7407
|
throw new RangeError("autoScaleInterval must be an integer of at least 1000 milliseconds.");
|
|
6000
7408
|
if (options.spawnDelay !== undefined && (!Number.isFinite(options.spawnDelay) || options.spawnDelay < 0))
|
|
6001
7409
|
throw new RangeError("spawnDelay must be a non-negative finite number of milliseconds.");
|
|
7410
|
+
if (options.maxConcurrency !== undefined && (!Number.isInteger(options.maxConcurrency) || options.maxConcurrency < 1))
|
|
7411
|
+
throw new RangeError("maxConcurrency must be a positive integer.");
|
|
7412
|
+
if (options.handshakeTimeout !== undefined && (!Number.isFinite(options.handshakeTimeout) || options.handshakeTimeout < 0))
|
|
7413
|
+
throw new RangeError("handshakeTimeout must be a non-negative number of milliseconds.");
|
|
6002
7414
|
this.#auto = options.shardCount === "auto";
|
|
6003
7415
|
this.#options = {
|
|
6004
7416
|
spawnDelay: ShardManager.IDENTIFY_INTERVAL,
|
|
@@ -6008,10 +7420,13 @@ class ShardManager {
|
|
|
6008
7420
|
this.#initialize(count);
|
|
6009
7421
|
}
|
|
6010
7422
|
async fetchRecommendedShardCount() {
|
|
7423
|
+
return (await this.fetchGatewayInfo()).shards;
|
|
7424
|
+
}
|
|
7425
|
+
async fetchGatewayInfo() {
|
|
6011
7426
|
const response = await fetch("https://discord.com/api/v10/gateway/bot", {
|
|
6012
7427
|
headers: {
|
|
6013
7428
|
Authorization: `Bot ${this.#options.token}`,
|
|
6014
|
-
"User-Agent":
|
|
7429
|
+
"User-Agent": `Lunibee/${package_default2.version}`
|
|
6015
7430
|
}
|
|
6016
7431
|
});
|
|
6017
7432
|
if (!response.ok)
|
|
@@ -6019,7 +7434,17 @@ class ShardManager {
|
|
|
6019
7434
|
const data = await response.json();
|
|
6020
7435
|
if (typeof data.shards !== "number" || !Number.isInteger(data.shards) || data.shards < 1)
|
|
6021
7436
|
throw new Error("Gateway discovery returned an invalid shard count.");
|
|
6022
|
-
|
|
7437
|
+
const limit = data.session_start_limit;
|
|
7438
|
+
const info = { shards: data.shards };
|
|
7439
|
+
if (limit && typeof limit.total === "number" && typeof limit.remaining === "number" && typeof limit.reset_after === "number" && typeof limit.max_concurrency === "number")
|
|
7440
|
+
info.sessionStartLimit = {
|
|
7441
|
+
total: limit.total,
|
|
7442
|
+
remaining: limit.remaining,
|
|
7443
|
+
resetAfter: limit.reset_after,
|
|
7444
|
+
maxConcurrency: Math.max(1, limit.max_concurrency)
|
|
7445
|
+
};
|
|
7446
|
+
this.#gatewayInfo = info;
|
|
7447
|
+
return info;
|
|
6023
7448
|
}
|
|
6024
7449
|
async connect() {
|
|
6025
7450
|
if (this.#autoScaleTimer) {
|
|
@@ -6027,17 +7452,25 @@ class ShardManager {
|
|
|
6027
7452
|
this.#autoScaleTimer = undefined;
|
|
6028
7453
|
}
|
|
6029
7454
|
await this.#ensureInitialized();
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
}
|
|
7455
|
+
const limit = this.#gatewayInfo?.sessionStartLimit;
|
|
7456
|
+
const ids = [...this.shards].filter(([, gateway]) => needsConnection(gateway)).map(([id]) => id);
|
|
7457
|
+
if (limit && limit.remaining < ids.length)
|
|
7458
|
+
throw new Error(`Session start limit exhausted: ${limit.remaining} of ${limit.total} IDENTIFYs left for ${ids.length} shards; resets in ${Math.ceil(limit.resetAfter / 1000)}s.`);
|
|
7459
|
+
const concurrency = Math.min(this.#options.maxConcurrency ?? limit?.maxConcurrency ?? 1, limit?.maxConcurrency ?? Infinity);
|
|
7460
|
+
for (let start = 0;start < ids.length; start += concurrency) {
|
|
7461
|
+
const round = ids.slice(start, start + concurrency);
|
|
7462
|
+
const results = await Promise.allSettled(round.map((id) => this.shards.get(id).connect()));
|
|
7463
|
+
const failed = results.findIndex((result) => result.status === "rejected");
|
|
7464
|
+
if (failed !== -1) {
|
|
6034
7465
|
this.destroy();
|
|
6035
|
-
throw new Error(`Failed to connect shard ${
|
|
6036
|
-
cause:
|
|
7466
|
+
throw new Error(`Failed to connect shard ${round[failed]}.`, {
|
|
7467
|
+
cause: results[failed].reason
|
|
6037
7468
|
});
|
|
6038
7469
|
}
|
|
6039
|
-
if (
|
|
7470
|
+
if (start + concurrency < ids.length && this.#options.spawnDelay && this.#options.spawnDelay > 0) {
|
|
7471
|
+
await Promise.all(round.map((id) => handshakeSent(this.shards.get(id), this.#options.handshakeTimeout ?? 15000)));
|
|
6040
7472
|
await sleep3(this.#options.spawnDelay);
|
|
7473
|
+
}
|
|
6041
7474
|
}
|
|
6042
7475
|
if (this.#options.autoScaleInterval && !this.#autoScaleTimer) {
|
|
6043
7476
|
this.#autoScaleTimer = setInterval(() => {
|
|
@@ -6080,6 +7513,13 @@ class ShardManager {
|
|
|
6080
7513
|
get(id) {
|
|
6081
7514
|
return this.shards.get(id);
|
|
6082
7515
|
}
|
|
7516
|
+
health() {
|
|
7517
|
+
return [...this.shards].map(([id, gateway]) => ({
|
|
7518
|
+
id,
|
|
7519
|
+
state: gateway.state,
|
|
7520
|
+
ping: gateway.ping
|
|
7521
|
+
}));
|
|
7522
|
+
}
|
|
6083
7523
|
values() {
|
|
6084
7524
|
return [...this.shards].map(([id, gateway]) => ({ id, gateway }));
|
|
6085
7525
|
}
|
|
@@ -6108,6 +7548,187 @@ class ShardManager {
|
|
|
6108
7548
|
});
|
|
6109
7549
|
}
|
|
6110
7550
|
}
|
|
7551
|
+
// packages/utils/src/args.ts
|
|
7552
|
+
var SNOWFLAKE = /^\d{16,22}$/;
|
|
7553
|
+
var TRUE_WORDS = new Set([
|
|
7554
|
+
"true",
|
|
7555
|
+
"yes",
|
|
7556
|
+
"y",
|
|
7557
|
+
"on",
|
|
7558
|
+
"1",
|
|
7559
|
+
"enable",
|
|
7560
|
+
"enabled"
|
|
7561
|
+
]);
|
|
7562
|
+
var FALSE_WORDS = new Set([
|
|
7563
|
+
"false",
|
|
7564
|
+
"no",
|
|
7565
|
+
"n",
|
|
7566
|
+
"off",
|
|
7567
|
+
"0",
|
|
7568
|
+
"disable",
|
|
7569
|
+
"disabled"
|
|
7570
|
+
]);
|
|
7571
|
+
function tokenizeArgs(input) {
|
|
7572
|
+
const args = [];
|
|
7573
|
+
let current = "";
|
|
7574
|
+
let quote = null;
|
|
7575
|
+
let started = false;
|
|
7576
|
+
for (let index = 0;index < input.length; index++) {
|
|
7577
|
+
const character = input[index];
|
|
7578
|
+
if (character === "\\" && index + 1 < input.length) {
|
|
7579
|
+
current += input[++index];
|
|
7580
|
+
started = true;
|
|
7581
|
+
} else if (quote) {
|
|
7582
|
+
if (character === quote)
|
|
7583
|
+
quote = null;
|
|
7584
|
+
else
|
|
7585
|
+
current += character;
|
|
7586
|
+
} else if (character === '"' || character === "'") {
|
|
7587
|
+
if (started)
|
|
7588
|
+
current += character;
|
|
7589
|
+
else {
|
|
7590
|
+
quote = character;
|
|
7591
|
+
started = true;
|
|
7592
|
+
}
|
|
7593
|
+
} else if (/\s/.test(character)) {
|
|
7594
|
+
if (started)
|
|
7595
|
+
args.push(current);
|
|
7596
|
+
current = "";
|
|
7597
|
+
started = false;
|
|
7598
|
+
} else {
|
|
7599
|
+
current += character;
|
|
7600
|
+
started = true;
|
|
7601
|
+
}
|
|
7602
|
+
}
|
|
7603
|
+
if (started)
|
|
7604
|
+
args.push(current);
|
|
7605
|
+
return args;
|
|
7606
|
+
}
|
|
7607
|
+
function parseUserMention(value) {
|
|
7608
|
+
const id = /^<@!?(\d{16,22})>$/.exec(value)?.[1] ?? value;
|
|
7609
|
+
return SNOWFLAKE.test(id) ? id : null;
|
|
7610
|
+
}
|
|
7611
|
+
function parseRoleMention(value) {
|
|
7612
|
+
const id = /^<@&(\d{16,22})>$/.exec(value)?.[1] ?? value;
|
|
7613
|
+
return SNOWFLAKE.test(id) ? id : null;
|
|
7614
|
+
}
|
|
7615
|
+
function parseChannelMention(value) {
|
|
7616
|
+
const id = /^<#(\d{16,22})>$/.exec(value)?.[1] ?? value;
|
|
7617
|
+
return SNOWFLAKE.test(id) ? id : null;
|
|
7618
|
+
}
|
|
7619
|
+
function parseMentionable(value) {
|
|
7620
|
+
const role = /^<@&(\d{16,22})>$/.exec(value)?.[1];
|
|
7621
|
+
if (role)
|
|
7622
|
+
return { id: role, type: "role" };
|
|
7623
|
+
const user = parseUserMention(value);
|
|
7624
|
+
return user ? { id: user, type: "user" } : null;
|
|
7625
|
+
}
|
|
7626
|
+
function readOne(spec, raw) {
|
|
7627
|
+
switch (spec.type) {
|
|
7628
|
+
case "string":
|
|
7629
|
+
case "rest":
|
|
7630
|
+
if (spec.maxLength !== undefined && raw.length > spec.maxLength)
|
|
7631
|
+
return {
|
|
7632
|
+
error: `must be at most ${spec.maxLength} characters`
|
|
7633
|
+
};
|
|
7634
|
+
if (spec.choices && !spec.choices.some((choice) => String(choice).toLowerCase() === raw.toLowerCase()))
|
|
7635
|
+
return { error: `must be one of: ${spec.choices.join(", ")}` };
|
|
7636
|
+
return { value: raw };
|
|
7637
|
+
case "integer":
|
|
7638
|
+
case "number": {
|
|
7639
|
+
const value = Number(raw);
|
|
7640
|
+
if (!Number.isFinite(value) || raw.trim() === "")
|
|
7641
|
+
return { error: "must be a number" };
|
|
7642
|
+
if (spec.type === "integer" && !Number.isSafeInteger(value))
|
|
7643
|
+
return { error: "must be a whole number" };
|
|
7644
|
+
if (spec.min !== undefined && value < spec.min)
|
|
7645
|
+
return { error: `must be at least ${spec.min}` };
|
|
7646
|
+
if (spec.max !== undefined && value > spec.max)
|
|
7647
|
+
return { error: `must be at most ${spec.max}` };
|
|
7648
|
+
if (spec.choices && !spec.choices.includes(value))
|
|
7649
|
+
return { error: `must be one of: ${spec.choices.join(", ")}` };
|
|
7650
|
+
return { value };
|
|
7651
|
+
}
|
|
7652
|
+
case "boolean": {
|
|
7653
|
+
const word = raw.toLowerCase();
|
|
7654
|
+
if (TRUE_WORDS.has(word))
|
|
7655
|
+
return { value: true };
|
|
7656
|
+
if (FALSE_WORDS.has(word))
|
|
7657
|
+
return { value: false };
|
|
7658
|
+
return { error: "must be yes or no" };
|
|
7659
|
+
}
|
|
7660
|
+
case "user": {
|
|
7661
|
+
const id = parseUserMention(raw);
|
|
7662
|
+
return id ? { value: id } : { error: "must be a user mention or ID" };
|
|
7663
|
+
}
|
|
7664
|
+
case "role": {
|
|
7665
|
+
const id = parseRoleMention(raw);
|
|
7666
|
+
return id ? { value: id } : { error: "must be a role mention or ID" };
|
|
7667
|
+
}
|
|
7668
|
+
case "channel": {
|
|
7669
|
+
const id = parseChannelMention(raw);
|
|
7670
|
+
return id ? { value: id } : { error: "must be a channel mention or ID" };
|
|
7671
|
+
}
|
|
7672
|
+
case "mentionable": {
|
|
7673
|
+
const value = parseMentionable(raw);
|
|
7674
|
+
return value ? { value } : { error: "must be a user or role mention" };
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
}
|
|
7678
|
+
function parsePrefixArgs(input, specs) {
|
|
7679
|
+
const args = typeof input === "string" ? tokenizeArgs(input) : [...input];
|
|
7680
|
+
const values = {};
|
|
7681
|
+
let position = 0;
|
|
7682
|
+
for (const [index, spec] of specs.entries()) {
|
|
7683
|
+
if (spec.type === "rest" && index !== specs.length - 1)
|
|
7684
|
+
throw new TypeError(`The rest argument "${spec.name}" must be the last one.`);
|
|
7685
|
+
const raw = spec.type === "rest" ? args.slice(position).join(" ") : args[position];
|
|
7686
|
+
if (raw === undefined || raw === "") {
|
|
7687
|
+
if (spec.required)
|
|
7688
|
+
return { ok: false, arg: spec.name, error: "is required" };
|
|
7689
|
+
values[spec.name] = undefined;
|
|
7690
|
+
continue;
|
|
7691
|
+
}
|
|
7692
|
+
const read = readOne(spec, raw);
|
|
7693
|
+
if ("error" in read)
|
|
7694
|
+
return { ok: false, arg: spec.name, error: read.error };
|
|
7695
|
+
values[spec.name] = read.value;
|
|
7696
|
+
position += spec.type === "rest" ? args.length : 1;
|
|
7697
|
+
}
|
|
7698
|
+
return { ok: true, values };
|
|
7699
|
+
}
|
|
7700
|
+
var OPTION_TYPES = {
|
|
7701
|
+
3: "string",
|
|
7702
|
+
4: "integer",
|
|
7703
|
+
5: "boolean",
|
|
7704
|
+
6: "user",
|
|
7705
|
+
7: "channel",
|
|
7706
|
+
8: "role",
|
|
7707
|
+
9: "mentionable",
|
|
7708
|
+
10: "number"
|
|
7709
|
+
};
|
|
7710
|
+
function argsFromCommandOptions(options, restLast = false) {
|
|
7711
|
+
const specs = [];
|
|
7712
|
+
for (const option of options) {
|
|
7713
|
+
const type = OPTION_TYPES[option.type];
|
|
7714
|
+
if (!type)
|
|
7715
|
+
continue;
|
|
7716
|
+
specs.push({
|
|
7717
|
+
name: option.name,
|
|
7718
|
+
type,
|
|
7719
|
+
required: option.required,
|
|
7720
|
+
min: option.min_value,
|
|
7721
|
+
max: option.max_value,
|
|
7722
|
+
maxLength: option.max_length,
|
|
7723
|
+
choices: option.choices?.map((choice) => choice.value)
|
|
7724
|
+
});
|
|
7725
|
+
}
|
|
7726
|
+
const last = specs[specs.length - 1];
|
|
7727
|
+
if (restLast && last?.type === "string")
|
|
7728
|
+
last.type = "rest";
|
|
7729
|
+
return specs;
|
|
7730
|
+
}
|
|
7731
|
+
|
|
6111
7732
|
// packages/utils/src/index.ts
|
|
6112
7733
|
function sleep4(ms) {
|
|
6113
7734
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -6203,12 +7824,14 @@ class VoiceConnection {
|
|
|
6203
7824
|
if (this.state === "destroyed" /* Destroyed */)
|
|
6204
7825
|
return;
|
|
6205
7826
|
this.#closeTransports();
|
|
7827
|
+
this.receiver.close();
|
|
6206
7828
|
this.#transition("disconnected" /* Disconnected */);
|
|
6207
7829
|
}
|
|
6208
7830
|
destroy() {
|
|
6209
7831
|
if (this.state === "destroyed" /* Destroyed */)
|
|
6210
7832
|
return;
|
|
6211
7833
|
this.#closeTransports();
|
|
7834
|
+
this.receiver.close();
|
|
6212
7835
|
this.channelId = undefined;
|
|
6213
7836
|
this.#transition("destroyed" /* Destroyed */);
|
|
6214
7837
|
this.#listeners.clear();
|
|
@@ -6416,6 +8039,8 @@ class VoiceReceiver {
|
|
|
6416
8039
|
this.#ssrcMap.set(ssrc, userId);
|
|
6417
8040
|
}
|
|
6418
8041
|
subscribe(userId) {
|
|
8042
|
+
if (this.connection.state === "destroyed" /* Destroyed */)
|
|
8043
|
+
throw new VoiceError("Voice connection has been destroyed.");
|
|
6419
8044
|
let controllerRef;
|
|
6420
8045
|
const stream = new ReadableStream({
|
|
6421
8046
|
start: (controller) => {
|
|
@@ -6436,6 +8061,16 @@ class VoiceReceiver {
|
|
|
6436
8061
|
});
|
|
6437
8062
|
return new AudioStream(stream, { title: `User ${userId} Audio` });
|
|
6438
8063
|
}
|
|
8064
|
+
close() {
|
|
8065
|
+
for (const controllers of this.#streams.values())
|
|
8066
|
+
for (const controller of controllers) {
|
|
8067
|
+
try {
|
|
8068
|
+
controller.close();
|
|
8069
|
+
} catch {}
|
|
8070
|
+
}
|
|
8071
|
+
this.#streams.clear();
|
|
8072
|
+
this.#ssrcMap.clear();
|
|
8073
|
+
}
|
|
6439
8074
|
onPacket(packet) {
|
|
6440
8075
|
if (packet.length < 12)
|
|
6441
8076
|
return;
|
|
@@ -6516,15 +8151,24 @@ function entersState(target, status, timeoutMs) {
|
|
|
6516
8151
|
class EmbedBuilder {
|
|
6517
8152
|
#data = {};
|
|
6518
8153
|
setTitle(value) {
|
|
6519
|
-
|
|
8154
|
+
if (value === null)
|
|
8155
|
+
delete this.#data.title;
|
|
8156
|
+
else
|
|
8157
|
+
this.#data.title = validate(value, 256, "Embed title");
|
|
6520
8158
|
return this;
|
|
6521
8159
|
}
|
|
6522
8160
|
setDescription(value) {
|
|
6523
|
-
|
|
8161
|
+
if (value === null)
|
|
8162
|
+
delete this.#data.description;
|
|
8163
|
+
else
|
|
8164
|
+
this.#data.description = validate(value, 4096, "Embed description");
|
|
6524
8165
|
return this;
|
|
6525
8166
|
}
|
|
6526
8167
|
setURL(value) {
|
|
6527
|
-
|
|
8168
|
+
if (value === null)
|
|
8169
|
+
delete this.#data.url;
|
|
8170
|
+
else
|
|
8171
|
+
this.#data.url = url(value, "Embed URL");
|
|
6528
8172
|
return this;
|
|
6529
8173
|
}
|
|
6530
8174
|
setColor(value) {
|
|
@@ -6556,11 +8200,19 @@ class EmbedBuilder {
|
|
|
6556
8200
|
return this;
|
|
6557
8201
|
}
|
|
6558
8202
|
setThumbnail(value) {
|
|
8203
|
+
if (value === null) {
|
|
8204
|
+
delete this.#data.thumbnail;
|
|
8205
|
+
return this;
|
|
8206
|
+
}
|
|
6559
8207
|
const valueURL = typeof value === "string" ? value : value.url;
|
|
6560
8208
|
this.#data.thumbnail = { url: url(valueURL, "Thumbnail URL") };
|
|
6561
8209
|
return this;
|
|
6562
8210
|
}
|
|
6563
8211
|
setImage(value) {
|
|
8212
|
+
if (value === null) {
|
|
8213
|
+
delete this.#data.image;
|
|
8214
|
+
return this;
|
|
8215
|
+
}
|
|
6564
8216
|
const valueURL = typeof value === "string" ? value : value.url;
|
|
6565
8217
|
this.#data.image = { url: url(valueURL, "Image URL") };
|
|
6566
8218
|
return this;
|
|
@@ -6663,10 +8315,13 @@ class ActionRowBuilder {
|
|
|
6663
8315
|
return this;
|
|
6664
8316
|
}
|
|
6665
8317
|
toJSON() {
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
8318
|
+
const components = this.#components.map((component) => component.toJSON());
|
|
8319
|
+
if (components.length === 0)
|
|
8320
|
+
throw new RangeError("An action row needs at least one component.");
|
|
8321
|
+
const types = components.map((component) => component.type);
|
|
8322
|
+
if (types.some((type) => type !== ComponentType.Button) && components.length > 1)
|
|
8323
|
+
throw new RangeError("A select menu or text input must be alone in its action row.");
|
|
8324
|
+
return { type: ComponentType.ActionRow, components };
|
|
6670
8325
|
}
|
|
6671
8326
|
}
|
|
6672
8327
|
|
|
@@ -6721,6 +8376,12 @@ class StringSelectBuilder {
|
|
|
6721
8376
|
return this;
|
|
6722
8377
|
}
|
|
6723
8378
|
toJSON() {
|
|
8379
|
+
assertSelect(this.#data);
|
|
8380
|
+
const count = this.#data.options?.length ?? 0;
|
|
8381
|
+
if (count === 0)
|
|
8382
|
+
throw new RangeError("A string select needs at least one option.");
|
|
8383
|
+
if ((this.#data.max_values ?? 1) > count)
|
|
8384
|
+
throw new RangeError("max_values cannot exceed the number of options.");
|
|
6724
8385
|
return structuredClone(this.#data);
|
|
6725
8386
|
}
|
|
6726
8387
|
}
|
|
@@ -6731,9 +8392,20 @@ class ButtonBuilder {
|
|
|
6731
8392
|
style: ButtonStyle.Secondary
|
|
6732
8393
|
};
|
|
6733
8394
|
setStyle(style) {
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
8395
|
+
const data = this.#data;
|
|
8396
|
+
data.style = style;
|
|
8397
|
+
if (style === ButtonStyle.Link) {
|
|
8398
|
+
delete data.custom_id;
|
|
8399
|
+
delete data.sku_id;
|
|
8400
|
+
} else if (style === ButtonStyle.Premium) {
|
|
8401
|
+
delete data.custom_id;
|
|
8402
|
+
delete data.url;
|
|
8403
|
+
delete data.label;
|
|
8404
|
+
delete data.emoji;
|
|
8405
|
+
} else {
|
|
8406
|
+
delete data.url;
|
|
8407
|
+
delete data.sku_id;
|
|
8408
|
+
}
|
|
6737
8409
|
return this;
|
|
6738
8410
|
}
|
|
6739
8411
|
setCustomId(value) {
|
|
@@ -6758,11 +8430,16 @@ class ButtonBuilder {
|
|
|
6758
8430
|
cause: error
|
|
6759
8431
|
});
|
|
6760
8432
|
}
|
|
6761
|
-
this
|
|
6762
|
-
delete this.#data.custom_id;
|
|
8433
|
+
this.setStyle(ButtonStyle.Link);
|
|
6763
8434
|
this.#data.url = url.toString();
|
|
6764
8435
|
return this;
|
|
6765
8436
|
}
|
|
8437
|
+
setSKUId(skuId) {
|
|
8438
|
+
validateText(skuId, 20, "Button SKU ID");
|
|
8439
|
+
this.setStyle(ButtonStyle.Premium);
|
|
8440
|
+
this.#data.sku_id = skuId;
|
|
8441
|
+
return this;
|
|
8442
|
+
}
|
|
6766
8443
|
setEmoji(emoji) {
|
|
6767
8444
|
this.#data.emoji = typeof emoji === "string" ? { name: emoji } : { ...emoji };
|
|
6768
8445
|
return this;
|
|
@@ -6772,7 +8449,26 @@ class ButtonBuilder {
|
|
|
6772
8449
|
return this;
|
|
6773
8450
|
}
|
|
6774
8451
|
toJSON() {
|
|
6775
|
-
|
|
8452
|
+
const data = this.#data;
|
|
8453
|
+
if (data.style === ButtonStyle.Link) {
|
|
8454
|
+
if (!data.url)
|
|
8455
|
+
throw new TypeError("Link buttons require a URL.");
|
|
8456
|
+
if (data.custom_id || data.sku_id)
|
|
8457
|
+
throw new TypeError("Link buttons cannot have a custom ID or SKU ID.");
|
|
8458
|
+
} else if (data.style === ButtonStyle.Premium) {
|
|
8459
|
+
if (!data.sku_id)
|
|
8460
|
+
throw new TypeError("Premium buttons require a SKU ID.");
|
|
8461
|
+
if (data.custom_id || data.url || data.label || data.emoji)
|
|
8462
|
+
throw new TypeError("Premium buttons cannot have a custom ID, URL, label or emoji.");
|
|
8463
|
+
} else {
|
|
8464
|
+
if (!data.custom_id)
|
|
8465
|
+
throw new TypeError("Non-link buttons require a custom ID.");
|
|
8466
|
+
if (data.url || data.sku_id)
|
|
8467
|
+
throw new TypeError("Only link buttons have a URL and only premium buttons have a SKU ID.");
|
|
8468
|
+
}
|
|
8469
|
+
if (data.style !== ButtonStyle.Premium && !data.label && !data.emoji)
|
|
8470
|
+
throw new TypeError("Buttons require a label or an emoji.");
|
|
8471
|
+
return structuredClone(data);
|
|
6776
8472
|
}
|
|
6777
8473
|
}
|
|
6778
8474
|
|
|
@@ -6816,6 +8512,7 @@ class EntitySelectBuilder {
|
|
|
6816
8512
|
return this;
|
|
6817
8513
|
}
|
|
6818
8514
|
toJSON() {
|
|
8515
|
+
assertSelect(this.#data);
|
|
6819
8516
|
return structuredClone(this.#data);
|
|
6820
8517
|
}
|
|
6821
8518
|
}
|
|
@@ -6842,11 +8539,18 @@ class ModalBuilder {
|
|
|
6842
8539
|
this.#components.push(...components);
|
|
6843
8540
|
return this;
|
|
6844
8541
|
}
|
|
8542
|
+
addTextInputs(...inputs) {
|
|
8543
|
+
return this.addComponents(...inputs.map((input) => new ActionRowBuilder().addComponents(input)));
|
|
8544
|
+
}
|
|
6845
8545
|
toJSON() {
|
|
8546
|
+
if (!this.#custom_id || !this.#title)
|
|
8547
|
+
throw new TypeError("Modals require a custom ID and a title.");
|
|
8548
|
+
if (this.#components.length === 0)
|
|
8549
|
+
throw new RangeError("Modals require at least one component.");
|
|
6846
8550
|
return {
|
|
6847
8551
|
type: 9,
|
|
6848
|
-
|
|
6849
|
-
|
|
8552
|
+
custom_id: this.#custom_id,
|
|
8553
|
+
title: this.#title,
|
|
6850
8554
|
components: this.#components.map((component) => component.toJSON())
|
|
6851
8555
|
};
|
|
6852
8556
|
}
|
|
@@ -6896,7 +8600,12 @@ class TextInputBuilder {
|
|
|
6896
8600
|
return this;
|
|
6897
8601
|
}
|
|
6898
8602
|
toJSON() {
|
|
6899
|
-
|
|
8603
|
+
const data = this.#data;
|
|
8604
|
+
if (!data.custom_id)
|
|
8605
|
+
throw new TypeError("Text inputs require a custom ID.");
|
|
8606
|
+
if (data.min_length !== undefined && data.max_length !== undefined && data.min_length > data.max_length)
|
|
8607
|
+
throw new RangeError("min_length cannot exceed max_length.");
|
|
8608
|
+
return structuredClone(data);
|
|
6900
8609
|
}
|
|
6901
8610
|
}
|
|
6902
8611
|
|
|
@@ -7123,6 +8832,23 @@ class ChannelSelectMenuBuilder extends EntitySelectBuilder {
|
|
|
7123
8832
|
super(ComponentType.ChannelSelect);
|
|
7124
8833
|
}
|
|
7125
8834
|
}
|
|
8835
|
+
function assertSelect(data) {
|
|
8836
|
+
if (!data.custom_id)
|
|
8837
|
+
throw new TypeError("Select menus require a custom ID.");
|
|
8838
|
+
if ((data.min_values ?? 1) > (data.max_values ?? 1))
|
|
8839
|
+
throw new RangeError("min_values cannot exceed max_values.");
|
|
8840
|
+
}
|
|
8841
|
+
var IS_COMPONENTS_V2 = 1 << 15;
|
|
8842
|
+
function componentsV2Message(components, options) {
|
|
8843
|
+
const list = Array.isArray(components) ? components : [components];
|
|
8844
|
+
if (!list.length)
|
|
8845
|
+
throw new TypeError("A Components V2 message needs at least one component.");
|
|
8846
|
+
return {
|
|
8847
|
+
...options ?? {},
|
|
8848
|
+
components: list.map((component) => component.toJSON()),
|
|
8849
|
+
flags: (options?.flags ?? 0) | IS_COMPONENTS_V2
|
|
8850
|
+
};
|
|
8851
|
+
}
|
|
7126
8852
|
// packages/builders/src/commands.ts
|
|
7127
8853
|
var ApplicationCommandOptionType2 = {
|
|
7128
8854
|
Subcommand: 1,
|
|
@@ -7637,6 +9363,8 @@ export {
|
|
|
7637
9363
|
GuildMemberManager,
|
|
7638
9364
|
GuildOnboarding,
|
|
7639
9365
|
GuildScheduledEventManager,
|
|
9366
|
+
GuildSoundboardManager,
|
|
9367
|
+
GuildStickerManager,
|
|
7640
9368
|
GuildWelcomeScreen,
|
|
7641
9369
|
HandlerRegistry,
|
|
7642
9370
|
HttpTransport,
|
|
@@ -7662,6 +9390,7 @@ export {
|
|
|
7662
9390
|
MessageManager,
|
|
7663
9391
|
ModalBuilder,
|
|
7664
9392
|
ModalSubmitInteraction,
|
|
9393
|
+
MonetizationManager,
|
|
7665
9394
|
NewsChannel,
|
|
7666
9395
|
NumberOptionBuilder,
|
|
7667
9396
|
OnboardingPrompt,
|
|
@@ -7731,6 +9460,7 @@ export {
|
|
|
7731
9460
|
WelcomeScreenChannel,
|
|
7732
9461
|
ZlibStreamDecoder,
|
|
7733
9462
|
abortError,
|
|
9463
|
+
argsFromCommandOptions,
|
|
7734
9464
|
blockQuote,
|
|
7735
9465
|
bold,
|
|
7736
9466
|
bulletList,
|
|
@@ -7739,6 +9469,8 @@ export {
|
|
|
7739
9469
|
classifyFrame,
|
|
7740
9470
|
classifyPayload,
|
|
7741
9471
|
codeBlock,
|
|
9472
|
+
componentsV2Message,
|
|
9473
|
+
computePermissions,
|
|
7742
9474
|
createAudioPlayer,
|
|
7743
9475
|
createAudioResource,
|
|
7744
9476
|
createChannel,
|
|
@@ -7761,7 +9493,13 @@ export {
|
|
|
7761
9493
|
masked,
|
|
7762
9494
|
normalizeRoutePath,
|
|
7763
9495
|
orderedList,
|
|
9496
|
+
parseChannelMention,
|
|
9497
|
+
parseMentionable,
|
|
9498
|
+
parsePrefixArgs,
|
|
9499
|
+
parseRoleMention,
|
|
9500
|
+
parseUserMention,
|
|
7764
9501
|
randomInt,
|
|
9502
|
+
redactPath,
|
|
7765
9503
|
resolveGatewayIntents,
|
|
7766
9504
|
resumePayload,
|
|
7767
9505
|
roleMention,
|
|
@@ -7772,8 +9510,10 @@ export {
|
|
|
7772
9510
|
strikethrough,
|
|
7773
9511
|
subtext,
|
|
7774
9512
|
timestamp,
|
|
9513
|
+
toRequest,
|
|
9514
|
+
tokenizeArgs,
|
|
7775
9515
|
underline,
|
|
7776
9516
|
userMention
|
|
7777
9517
|
};
|
|
7778
9518
|
|
|
7779
|
-
//# debugId=
|
|
9519
|
+
//# debugId=9E598E337B852A0164756E2164756E21
|