lunibee 0.1.8 → 0.2.0
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 +5 -0
- package/dist/builders/index.js +72 -12
- package/dist/builders/index.js.map +5 -5
- 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 +22 -8
- package/dist/core/index.js +1526 -124
- package/dist/core/index.js.map +26 -22
- package/dist/core/permissions.d.ts +48 -0
- package/dist/index.js +1578 -268
- package/dist/index.js.map +30 -29
- 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.d.ts +28 -2
- package/dist/managers/index.d.ts +37 -5
- package/dist/managers/index.js +870 -152
- package/dist/managers/index.js.map +18 -16
- package/dist/managers/message.d.ts +10 -1
- 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 +2 -0
- package/dist/structures/index.js +96 -42
- package/dist/structures/index.js.map +10 -9
- package/dist/structures/interactions.d.ts +26 -0
- package/dist/types/gateway.d.ts +16 -0
- package/dist/types/index.d.ts +55 -1
- package/dist/types/index.js.map +2 -2
- 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++) {
|
|
@@ -419,6 +432,35 @@ class PermissionsBitField extends PermissionSet {
|
|
|
419
432
|
super(value);
|
|
420
433
|
}
|
|
421
434
|
}
|
|
435
|
+
var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
|
|
436
|
+
var bits = (value) => new PermissionSet(value).bitfield;
|
|
437
|
+
function computePermissions(context) {
|
|
438
|
+
if (context.ownerId !== undefined && context.ownerId === context.memberId)
|
|
439
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
440
|
+
const roles = new Map(context.roles.map((role) => [role.id, role]));
|
|
441
|
+
let base = bits(roles.get(context.guildId)?.permissions ?? 0n);
|
|
442
|
+
for (const id of context.memberRoleIds)
|
|
443
|
+
base |= bits(roles.get(id)?.permissions ?? 0n);
|
|
444
|
+
if (base & Permission.administrator)
|
|
445
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
446
|
+
const overwrites = context.overwrites ?? [];
|
|
447
|
+
const everyone = overwrites.find((o) => o.id === context.guildId);
|
|
448
|
+
if (everyone)
|
|
449
|
+
base = base & ~bits(everyone.deny) | bits(everyone.allow);
|
|
450
|
+
const memberRoles = new Set(context.memberRoleIds);
|
|
451
|
+
let allow = 0n;
|
|
452
|
+
let deny = 0n;
|
|
453
|
+
for (const overwrite of overwrites)
|
|
454
|
+
if (overwrite.type === 0 /* Role */ && overwrite.id !== context.guildId && memberRoles.has(overwrite.id)) {
|
|
455
|
+
allow |= bits(overwrite.allow);
|
|
456
|
+
deny |= bits(overwrite.deny);
|
|
457
|
+
}
|
|
458
|
+
base = base & ~deny | allow;
|
|
459
|
+
const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
|
|
460
|
+
if (member)
|
|
461
|
+
base = base & ~bits(member.deny) | bits(member.allow);
|
|
462
|
+
return new PermissionSet(base);
|
|
463
|
+
}
|
|
422
464
|
// packages/core/src/events.ts
|
|
423
465
|
var ClientEvent;
|
|
424
466
|
((ClientEvent) => {
|
|
@@ -455,6 +497,13 @@ var ClientEvent;
|
|
|
455
497
|
ClientEvent["GuildRoleDelete"] = "guildRoleDelete";
|
|
456
498
|
ClientEvent["GuildEmojisUpdate"] = "guildEmojisUpdate";
|
|
457
499
|
ClientEvent["GuildStickersUpdate"] = "guildStickersUpdate";
|
|
500
|
+
ClientEvent["EntitlementCreate"] = "entitlementCreate";
|
|
501
|
+
ClientEvent["EntitlementUpdate"] = "entitlementUpdate";
|
|
502
|
+
ClientEvent["EntitlementDelete"] = "entitlementDelete";
|
|
503
|
+
ClientEvent["SoundboardSoundCreate"] = "soundboardSoundCreate";
|
|
504
|
+
ClientEvent["SoundboardSoundUpdate"] = "soundboardSoundUpdate";
|
|
505
|
+
ClientEvent["SoundboardSoundDelete"] = "soundboardSoundDelete";
|
|
506
|
+
ClientEvent["SoundboardSoundsUpdate"] = "soundboardSoundsUpdate";
|
|
458
507
|
ClientEvent["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
|
|
459
508
|
ClientEvent["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
|
|
460
509
|
ClientEvent["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
|
|
@@ -497,6 +546,9 @@ class Collector extends EventEmitter {
|
|
|
497
546
|
endReason;
|
|
498
547
|
totalProcessed = 0;
|
|
499
548
|
#timeoutTimer;
|
|
549
|
+
#idleTimer;
|
|
550
|
+
#onAbort = () => this.stop("abort");
|
|
551
|
+
#cleanup = [];
|
|
500
552
|
constructor(options = {}) {
|
|
501
553
|
super();
|
|
502
554
|
this.options = options;
|
|
@@ -505,6 +557,27 @@ class Collector extends EventEmitter {
|
|
|
505
557
|
this.stop("time");
|
|
506
558
|
}, options.time);
|
|
507
559
|
}
|
|
560
|
+
this.#resetIdle();
|
|
561
|
+
if (options.signal?.aborted)
|
|
562
|
+
this.stop("abort");
|
|
563
|
+
else
|
|
564
|
+
options.signal?.addEventListener("abort", this.#onAbort, {
|
|
565
|
+
once: true
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
onDispose(cleanup) {
|
|
569
|
+
if (this.ended)
|
|
570
|
+
cleanup();
|
|
571
|
+
else
|
|
572
|
+
this.#cleanup.push(cleanup);
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
#resetIdle() {
|
|
576
|
+
if (!this.options.idle || this.options.idle <= 0)
|
|
577
|
+
return;
|
|
578
|
+
if (this.#idleTimer)
|
|
579
|
+
clearTimeout(this.#idleTimer);
|
|
580
|
+
this.#idleTimer = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
508
581
|
}
|
|
509
582
|
async handle(key, item) {
|
|
510
583
|
if (this.ended)
|
|
@@ -522,6 +595,7 @@ class Collector extends EventEmitter {
|
|
|
522
595
|
return false;
|
|
523
596
|
}
|
|
524
597
|
this.collected.set(key, item);
|
|
598
|
+
this.#resetIdle();
|
|
525
599
|
this.emit("collect", item);
|
|
526
600
|
if (this.options.max && this.collected.size >= this.options.max) {
|
|
527
601
|
this.stop("limit");
|
|
@@ -540,9 +614,53 @@ class Collector extends EventEmitter {
|
|
|
540
614
|
this.endReason = reason;
|
|
541
615
|
if (this.#timeoutTimer)
|
|
542
616
|
clearTimeout(this.#timeoutTimer);
|
|
617
|
+
if (this.#idleTimer)
|
|
618
|
+
clearTimeout(this.#idleTimer);
|
|
619
|
+
this.options.signal?.removeEventListener("abort", this.#onAbort);
|
|
620
|
+
for (const cleanup of this.#cleanup.splice(0)) {
|
|
621
|
+
try {
|
|
622
|
+
cleanup();
|
|
623
|
+
} catch {}
|
|
624
|
+
}
|
|
543
625
|
this.emit("end", this.collected, reason);
|
|
544
626
|
this.removeAllListeners();
|
|
545
627
|
}
|
|
628
|
+
wait() {
|
|
629
|
+
if (this.ended)
|
|
630
|
+
return Promise.resolve(this.collected);
|
|
631
|
+
return new Promise((resolve) => this.once("end", (collected) => resolve(collected)));
|
|
632
|
+
}
|
|
633
|
+
async* [Symbol.asyncIterator]() {
|
|
634
|
+
const queue = [];
|
|
635
|
+
let wake;
|
|
636
|
+
const onCollect = (item) => {
|
|
637
|
+
queue.push(item);
|
|
638
|
+
wake?.();
|
|
639
|
+
};
|
|
640
|
+
const onEnd = () => wake?.();
|
|
641
|
+
if (!this.ended) {
|
|
642
|
+
this.on("collect", onCollect);
|
|
643
|
+
this.on("end", onEnd);
|
|
644
|
+
}
|
|
645
|
+
try {
|
|
646
|
+
for (;; ) {
|
|
647
|
+
if (queue.length > 0) {
|
|
648
|
+
yield queue.shift();
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (this.ended)
|
|
652
|
+
return;
|
|
653
|
+
await new Promise((resolve) => wake = resolve);
|
|
654
|
+
wake = undefined;
|
|
655
|
+
}
|
|
656
|
+
} finally {
|
|
657
|
+
this.off("collect", onCollect);
|
|
658
|
+
this.off("end", onEnd);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
[Symbol.dispose]() {
|
|
662
|
+
this.stop("disposed");
|
|
663
|
+
}
|
|
546
664
|
next() {
|
|
547
665
|
return new Promise((resolve, reject) => {
|
|
548
666
|
if (this.ended) {
|
|
@@ -858,7 +976,340 @@ class Cache {
|
|
|
858
976
|
}
|
|
859
977
|
|
|
860
978
|
// packages/collection/src/index.ts
|
|
979
|
+
class RecencyList {
|
|
980
|
+
#nodes = new Map;
|
|
981
|
+
#oldest;
|
|
982
|
+
#newest;
|
|
983
|
+
get size() {
|
|
984
|
+
return this.#nodes.size;
|
|
985
|
+
}
|
|
986
|
+
oldest() {
|
|
987
|
+
return this.#oldest?.key;
|
|
988
|
+
}
|
|
989
|
+
touch(key) {
|
|
990
|
+
const node = this.#nodes.get(key);
|
|
991
|
+
if (node)
|
|
992
|
+
return this.#moveNewest(node);
|
|
993
|
+
const created = { key, older: this.#newest };
|
|
994
|
+
if (this.#newest)
|
|
995
|
+
this.#newest.newer = created;
|
|
996
|
+
else
|
|
997
|
+
this.#oldest = created;
|
|
998
|
+
this.#newest = created;
|
|
999
|
+
this.#nodes.set(key, created);
|
|
1000
|
+
}
|
|
1001
|
+
promote(key) {
|
|
1002
|
+
const node = this.#nodes.get(key);
|
|
1003
|
+
if (node)
|
|
1004
|
+
this.#moveNewest(node);
|
|
1005
|
+
}
|
|
1006
|
+
delete(key) {
|
|
1007
|
+
const node = this.#nodes.get(key);
|
|
1008
|
+
if (!node)
|
|
1009
|
+
return false;
|
|
1010
|
+
this.#unlink(node);
|
|
1011
|
+
this.#nodes.delete(key);
|
|
1012
|
+
return true;
|
|
1013
|
+
}
|
|
1014
|
+
clear() {
|
|
1015
|
+
this.#nodes.clear();
|
|
1016
|
+
this.#oldest = this.#newest = undefined;
|
|
1017
|
+
}
|
|
1018
|
+
#unlink(node) {
|
|
1019
|
+
if (node.older)
|
|
1020
|
+
node.older.newer = node.newer;
|
|
1021
|
+
else
|
|
1022
|
+
this.#oldest = node.newer;
|
|
1023
|
+
if (node.newer)
|
|
1024
|
+
node.newer.older = node.older;
|
|
1025
|
+
else
|
|
1026
|
+
this.#newest = node.older;
|
|
1027
|
+
node.older = node.newer = undefined;
|
|
1028
|
+
}
|
|
1029
|
+
#moveNewest(node) {
|
|
1030
|
+
if (node === this.#newest)
|
|
1031
|
+
return;
|
|
1032
|
+
this.#unlink(node);
|
|
1033
|
+
node.older = this.#newest;
|
|
1034
|
+
if (this.#newest)
|
|
1035
|
+
this.#newest.newer = node;
|
|
1036
|
+
else
|
|
1037
|
+
this.#oldest = node;
|
|
1038
|
+
this.#newest = node;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function assertTTL(ttl) {
|
|
1042
|
+
if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
|
|
1043
|
+
throw new RangeError("TTL must be a positive number, or omitted.");
|
|
1044
|
+
}
|
|
1045
|
+
|
|
861
1046
|
class Collection extends Map {
|
|
1047
|
+
#ttl;
|
|
1048
|
+
#maxSize;
|
|
1049
|
+
#onEvict;
|
|
1050
|
+
#expiry = new Map;
|
|
1051
|
+
#lru = new RecencyList;
|
|
1052
|
+
#stats = {
|
|
1053
|
+
hits: 0,
|
|
1054
|
+
misses: 0,
|
|
1055
|
+
expired: 0,
|
|
1056
|
+
evicted: 0
|
|
1057
|
+
};
|
|
1058
|
+
#heap = [];
|
|
1059
|
+
#timer;
|
|
1060
|
+
#armedFor = Infinity;
|
|
1061
|
+
constructor(entries, options = {}) {
|
|
1062
|
+
super();
|
|
1063
|
+
assertTTL(options.ttl);
|
|
1064
|
+
if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
|
|
1065
|
+
throw new RangeError("maxSize must be a positive integer.");
|
|
1066
|
+
this.#ttl = options.ttl;
|
|
1067
|
+
this.#maxSize = options.maxSize;
|
|
1068
|
+
this.#onEvict = options.onEvict;
|
|
1069
|
+
if (entries)
|
|
1070
|
+
for (const [key, value] of entries)
|
|
1071
|
+
this.set(key, value);
|
|
1072
|
+
}
|
|
1073
|
+
set(key, value, ttl) {
|
|
1074
|
+
assertTTL(ttl);
|
|
1075
|
+
const window = ttl ?? this.#ttl;
|
|
1076
|
+
if (this.#maxSize !== undefined) {
|
|
1077
|
+
this.#lru.touch(key);
|
|
1078
|
+
}
|
|
1079
|
+
super.set(key, value);
|
|
1080
|
+
if (window !== undefined)
|
|
1081
|
+
this.#schedule(key, window);
|
|
1082
|
+
else if (this.#expiry.size > 0)
|
|
1083
|
+
this.#expiry.delete(key);
|
|
1084
|
+
this.#enforceCap();
|
|
1085
|
+
return this;
|
|
1086
|
+
}
|
|
1087
|
+
setWithoutTTL(key, value) {
|
|
1088
|
+
if (this.#expiry.size > 0)
|
|
1089
|
+
this.#expiry.delete(key);
|
|
1090
|
+
if (this.#lru.size > 0)
|
|
1091
|
+
this.#lru.delete(key);
|
|
1092
|
+
super.set(key, value);
|
|
1093
|
+
return this;
|
|
1094
|
+
}
|
|
1095
|
+
get(key) {
|
|
1096
|
+
if (this.#expireIfDue(key)) {
|
|
1097
|
+
this.#stats.misses++;
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
const value = super.get(key);
|
|
1101
|
+
if (value === undefined && !super.has(key)) {
|
|
1102
|
+
this.#stats.misses++;
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
this.#stats.hits++;
|
|
1106
|
+
const expiry = this.#expiry.get(key);
|
|
1107
|
+
if (expiry)
|
|
1108
|
+
expiry.deadline = Date.now() + expiry.window;
|
|
1109
|
+
this.#lru.promote(key);
|
|
1110
|
+
return value;
|
|
1111
|
+
}
|
|
1112
|
+
peek(key) {
|
|
1113
|
+
if (!this.#expireIfDue(key) && super.has(key)) {
|
|
1114
|
+
this.#stats.hits++;
|
|
1115
|
+
return super.get(key);
|
|
1116
|
+
}
|
|
1117
|
+
this.#stats.misses++;
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
get stats() {
|
|
1121
|
+
return { ...this.#stats };
|
|
1122
|
+
}
|
|
1123
|
+
has(key) {
|
|
1124
|
+
return !this.#expireIfDue(key) && super.has(key);
|
|
1125
|
+
}
|
|
1126
|
+
delete(key) {
|
|
1127
|
+
if (this.#expireIfDue(key))
|
|
1128
|
+
return false;
|
|
1129
|
+
this.#expiry.delete(key);
|
|
1130
|
+
this.#lru.delete(key);
|
|
1131
|
+
return super.delete(key);
|
|
1132
|
+
}
|
|
1133
|
+
clear() {
|
|
1134
|
+
super.clear();
|
|
1135
|
+
this.#expiry.clear();
|
|
1136
|
+
this.#lru.clear();
|
|
1137
|
+
this.#heap.length = 0;
|
|
1138
|
+
if (this.#timer)
|
|
1139
|
+
clearTimeout(this.#timer);
|
|
1140
|
+
this.#timer = undefined;
|
|
1141
|
+
this.#armedFor = Infinity;
|
|
1142
|
+
}
|
|
1143
|
+
get size() {
|
|
1144
|
+
this.purge();
|
|
1145
|
+
return super.size;
|
|
1146
|
+
}
|
|
1147
|
+
entries() {
|
|
1148
|
+
this.purge();
|
|
1149
|
+
return super.entries();
|
|
1150
|
+
}
|
|
1151
|
+
keys() {
|
|
1152
|
+
this.purge();
|
|
1153
|
+
return super.keys();
|
|
1154
|
+
}
|
|
1155
|
+
values() {
|
|
1156
|
+
this.purge();
|
|
1157
|
+
return super.values();
|
|
1158
|
+
}
|
|
1159
|
+
[Symbol.iterator]() {
|
|
1160
|
+
return this.entries();
|
|
1161
|
+
}
|
|
1162
|
+
forEach(callback, thisArg) {
|
|
1163
|
+
this.purge();
|
|
1164
|
+
super.forEach(callback, thisArg);
|
|
1165
|
+
}
|
|
1166
|
+
ttlRemaining(key) {
|
|
1167
|
+
if (this.#expireIfDue(key))
|
|
1168
|
+
return;
|
|
1169
|
+
const expiry = this.#expiry.get(key);
|
|
1170
|
+
return expiry && Math.max(0, expiry.deadline - Date.now());
|
|
1171
|
+
}
|
|
1172
|
+
purge() {
|
|
1173
|
+
if (this.#expiry.size === 0)
|
|
1174
|
+
return 0;
|
|
1175
|
+
const now = Date.now();
|
|
1176
|
+
let removed = 0;
|
|
1177
|
+
const dropped = [];
|
|
1178
|
+
while (this.#nextDeadline() <= now) {
|
|
1179
|
+
const due = this.#heapPop();
|
|
1180
|
+
dropped.push([due.key, super.get(due.key)]);
|
|
1181
|
+
this.#remove(due.key);
|
|
1182
|
+
removed++;
|
|
1183
|
+
}
|
|
1184
|
+
this.#stats.expired += removed;
|
|
1185
|
+
this.#rearm();
|
|
1186
|
+
for (const [key, value] of dropped)
|
|
1187
|
+
this.#notify(key, value, "expired");
|
|
1188
|
+
return removed;
|
|
1189
|
+
}
|
|
1190
|
+
#expireIfDue(key) {
|
|
1191
|
+
const expiry = this.#expiry.get(key);
|
|
1192
|
+
if (!expiry || expiry.deadline > Date.now())
|
|
1193
|
+
return false;
|
|
1194
|
+
const value = super.get(key);
|
|
1195
|
+
this.#remove(key);
|
|
1196
|
+
this.#stats.expired++;
|
|
1197
|
+
this.#notify(key, value, "expired");
|
|
1198
|
+
return true;
|
|
1199
|
+
}
|
|
1200
|
+
#remove(key) {
|
|
1201
|
+
this.#expiry.delete(key);
|
|
1202
|
+
this.#lru.delete(key);
|
|
1203
|
+
super.delete(key);
|
|
1204
|
+
}
|
|
1205
|
+
#notify(key, value, reason) {
|
|
1206
|
+
if (!this.#onEvict)
|
|
1207
|
+
return;
|
|
1208
|
+
try {
|
|
1209
|
+
this.#onEvict(key, value, reason);
|
|
1210
|
+
} catch {}
|
|
1211
|
+
}
|
|
1212
|
+
#enforceCap() {
|
|
1213
|
+
if (this.#maxSize === undefined)
|
|
1214
|
+
return;
|
|
1215
|
+
while (this.#lru.size > this.#maxSize) {
|
|
1216
|
+
const oldest = this.#lru.oldest();
|
|
1217
|
+
const value = super.get(oldest);
|
|
1218
|
+
this.#remove(oldest);
|
|
1219
|
+
this.#stats.evicted++;
|
|
1220
|
+
this.#notify(oldest, value, "evicted");
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
#schedule(key, window) {
|
|
1224
|
+
const deadline = Date.now() + window;
|
|
1225
|
+
const expiry = this.#expiry.get(key);
|
|
1226
|
+
if (expiry) {
|
|
1227
|
+
expiry.deadline = deadline;
|
|
1228
|
+
expiry.window = window;
|
|
1229
|
+
if (deadline >= expiry.filed)
|
|
1230
|
+
return;
|
|
1231
|
+
expiry.filed = deadline;
|
|
1232
|
+
} else
|
|
1233
|
+
this.#expiry.set(key, { deadline, window, filed: deadline });
|
|
1234
|
+
this.#heapPush({ key, deadline });
|
|
1235
|
+
if (this.#heap.length > 2 * this.#expiry.size + 8)
|
|
1236
|
+
this.#compact();
|
|
1237
|
+
this.#rearm();
|
|
1238
|
+
}
|
|
1239
|
+
#nextDeadline() {
|
|
1240
|
+
for (;; ) {
|
|
1241
|
+
const top = this.#heap[0];
|
|
1242
|
+
if (top === undefined)
|
|
1243
|
+
return Infinity;
|
|
1244
|
+
const expiry = this.#expiry.get(top.key);
|
|
1245
|
+
if (!expiry || expiry.filed !== top.deadline) {
|
|
1246
|
+
this.#heapPop();
|
|
1247
|
+
continue;
|
|
1248
|
+
}
|
|
1249
|
+
if (expiry.deadline === top.deadline)
|
|
1250
|
+
return top.deadline;
|
|
1251
|
+
this.#heapPop();
|
|
1252
|
+
expiry.filed = expiry.deadline;
|
|
1253
|
+
this.#heapPush({ key: top.key, deadline: expiry.deadline });
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
#compact() {
|
|
1257
|
+
const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
|
|
1258
|
+
this.#heap.length = 0;
|
|
1259
|
+
for (const record of live)
|
|
1260
|
+
this.#heapPush(record);
|
|
1261
|
+
}
|
|
1262
|
+
#rearm() {
|
|
1263
|
+
const deadline = this.#nextDeadline();
|
|
1264
|
+
if (this.#timer !== undefined && deadline >= this.#armedFor)
|
|
1265
|
+
return;
|
|
1266
|
+
if (this.#timer)
|
|
1267
|
+
clearTimeout(this.#timer);
|
|
1268
|
+
this.#timer = undefined;
|
|
1269
|
+
this.#armedFor = deadline;
|
|
1270
|
+
if (deadline === Infinity)
|
|
1271
|
+
return;
|
|
1272
|
+
this.#timer = setTimeout(() => {
|
|
1273
|
+
this.#timer = undefined;
|
|
1274
|
+
this.#armedFor = Infinity;
|
|
1275
|
+
this.purge();
|
|
1276
|
+
}, Math.max(0, deadline - Date.now()));
|
|
1277
|
+
this.#timer.unref?.();
|
|
1278
|
+
}
|
|
1279
|
+
#heapPush(record) {
|
|
1280
|
+
const heap = this.#heap;
|
|
1281
|
+
heap.push(record);
|
|
1282
|
+
let i = heap.length - 1;
|
|
1283
|
+
while (i > 0) {
|
|
1284
|
+
const parent = i - 1 >> 1;
|
|
1285
|
+
if (heap[parent].deadline <= heap[i].deadline)
|
|
1286
|
+
break;
|
|
1287
|
+
[heap[parent], heap[i]] = [heap[i], heap[parent]];
|
|
1288
|
+
i = parent;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
#heapPop() {
|
|
1292
|
+
const heap = this.#heap;
|
|
1293
|
+
const top = heap[0];
|
|
1294
|
+
const last = heap.pop();
|
|
1295
|
+
if (top === undefined || heap.length === 0)
|
|
1296
|
+
return top;
|
|
1297
|
+
heap[0] = last;
|
|
1298
|
+
for (let i = 0;; ) {
|
|
1299
|
+
const left = 2 * i + 1;
|
|
1300
|
+
const right = left + 1;
|
|
1301
|
+
let smallest = i;
|
|
1302
|
+
if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
|
|
1303
|
+
smallest = left;
|
|
1304
|
+
if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
|
|
1305
|
+
smallest = right;
|
|
1306
|
+
if (smallest === i)
|
|
1307
|
+
break;
|
|
1308
|
+
[heap[smallest], heap[i]] = [heap[i], heap[smallest]];
|
|
1309
|
+
i = smallest;
|
|
1310
|
+
}
|
|
1311
|
+
return top;
|
|
1312
|
+
}
|
|
862
1313
|
first() {
|
|
863
1314
|
for (const value of this.values())
|
|
864
1315
|
return value;
|
|
@@ -1083,11 +1534,40 @@ class Manager {
|
|
|
1083
1534
|
has(id) {
|
|
1084
1535
|
return this.cache.has(id);
|
|
1085
1536
|
}
|
|
1537
|
+
#inflight = new Map;
|
|
1538
|
+
fetchOnce(id, load, store = (value) => {
|
|
1539
|
+
this.set(id, value);
|
|
1540
|
+
return value;
|
|
1541
|
+
}) {
|
|
1542
|
+
const pending = this.#inflight.get(id);
|
|
1543
|
+
if (pending)
|
|
1544
|
+
return pending.promise;
|
|
1545
|
+
const entry = {
|
|
1546
|
+
promise: new Promise((resolve) => resolve(load())),
|
|
1547
|
+
dirty: false
|
|
1548
|
+
};
|
|
1549
|
+
this.#inflight.set(id, entry);
|
|
1550
|
+
entry.promise = entry.promise.then((value) => {
|
|
1551
|
+
this.#inflight.delete(id);
|
|
1552
|
+
return entry.dirty ? this.get(id) ?? value : store(value);
|
|
1553
|
+
}, (error) => {
|
|
1554
|
+
this.#inflight.delete(id);
|
|
1555
|
+
throw error;
|
|
1556
|
+
});
|
|
1557
|
+
return entry.promise;
|
|
1558
|
+
}
|
|
1559
|
+
#markDirty(id) {
|
|
1560
|
+
const pending = this.#inflight.get(id);
|
|
1561
|
+
if (pending)
|
|
1562
|
+
pending.dirty = true;
|
|
1563
|
+
}
|
|
1086
1564
|
set(id, value) {
|
|
1087
|
-
this
|
|
1565
|
+
this.#markDirty(id);
|
|
1566
|
+
this.cache.setWithoutTTL(id, value);
|
|
1088
1567
|
return this;
|
|
1089
1568
|
}
|
|
1090
1569
|
delete(id) {
|
|
1570
|
+
this.#markDirty(id);
|
|
1091
1571
|
return this.cache.delete(id);
|
|
1092
1572
|
}
|
|
1093
1573
|
clear() {
|
|
@@ -1123,16 +1603,20 @@ class ResourceManager extends Manager {
|
|
|
1123
1603
|
async resolve(id) {
|
|
1124
1604
|
return this.get(id) ?? this.fetch(id);
|
|
1125
1605
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
this.set(id, resource);
|
|
1129
|
-
return resource;
|
|
1606
|
+
fetch(id) {
|
|
1607
|
+
return this.fetchOnce(id, () => this.#fetcher(id));
|
|
1130
1608
|
}
|
|
1131
1609
|
async fetchMany(ids) {
|
|
1132
1610
|
return Promise.all([...ids].map((id) => this.resolve(id)));
|
|
1133
1611
|
}
|
|
1134
1612
|
upsert(resource) {
|
|
1135
1613
|
const key = this.#key(resource);
|
|
1614
|
+
const existing = this.get(key);
|
|
1615
|
+
if (existing !== undefined && existing !== resource && typeof existing === "object" && existing !== null) {
|
|
1616
|
+
Object.assign(existing, resource);
|
|
1617
|
+
this.set(key, existing);
|
|
1618
|
+
return existing;
|
|
1619
|
+
}
|
|
1136
1620
|
this.set(key, resource);
|
|
1137
1621
|
return resource;
|
|
1138
1622
|
}
|
|
@@ -1143,7 +1627,7 @@ class ResourceManager extends Manager {
|
|
|
1143
1627
|
// packages/rest/package.json
|
|
1144
1628
|
var package_default = {
|
|
1145
1629
|
name: "@lunibee/rest",
|
|
1146
|
-
version: "0.
|
|
1630
|
+
version: "0.2.0",
|
|
1147
1631
|
type: "module",
|
|
1148
1632
|
module: "./src/index.ts",
|
|
1149
1633
|
types: "./src/index.ts",
|
|
@@ -1203,7 +1687,29 @@ class MemoryRateLimitStore {
|
|
|
1203
1687
|
}
|
|
1204
1688
|
|
|
1205
1689
|
// packages/rest/src/errors.ts
|
|
1690
|
+
function kindFromStatus(status) {
|
|
1691
|
+
if (status === 429)
|
|
1692
|
+
return "rateLimited";
|
|
1693
|
+
if (status === 401)
|
|
1694
|
+
return "authentication";
|
|
1695
|
+
if (status === 403)
|
|
1696
|
+
return "permission";
|
|
1697
|
+
if (status === 404)
|
|
1698
|
+
return "notFound";
|
|
1699
|
+
if (status === 400 || status === 422)
|
|
1700
|
+
return "validation";
|
|
1701
|
+
if (status >= 500)
|
|
1702
|
+
return "server";
|
|
1703
|
+
if (status === 0)
|
|
1704
|
+
return "network";
|
|
1705
|
+
return "client";
|
|
1706
|
+
}
|
|
1707
|
+
function redactPath(path) {
|
|
1708
|
+
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/, "$1:token");
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1206
1711
|
class RESTError extends Error {
|
|
1712
|
+
kind;
|
|
1207
1713
|
status;
|
|
1208
1714
|
code;
|
|
1209
1715
|
errors;
|
|
@@ -1213,14 +1719,18 @@ class RESTError extends Error {
|
|
|
1213
1719
|
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
1214
1720
|
this.name = "RESTError";
|
|
1215
1721
|
this.status = status;
|
|
1722
|
+
this.kind = options.kind ?? kindFromStatus(status);
|
|
1216
1723
|
this.code = code;
|
|
1217
1724
|
this.errors = errors;
|
|
1218
1725
|
this.method = options.method;
|
|
1219
|
-
this.path = options.path;
|
|
1726
|
+
this.path = options.path === undefined ? undefined : redactPath(options.path);
|
|
1727
|
+
}
|
|
1728
|
+
get retryable() {
|
|
1729
|
+
return this.kind === "rateLimited" || this.kind === "server" || this.kind === "network" || this.kind === "timeout";
|
|
1220
1730
|
}
|
|
1221
1731
|
}
|
|
1222
1732
|
function abortError(path, reason) {
|
|
1223
|
-
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason });
|
|
1733
|
+
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason, kind: "aborted" });
|
|
1224
1734
|
}
|
|
1225
1735
|
async function sleep(delay, signal, path) {
|
|
1226
1736
|
if (delay <= 0)
|
|
@@ -1555,8 +2065,23 @@ var Routes = {
|
|
|
1555
2065
|
invite: (code) => `/invites/${encodeURIComponent(code)}`,
|
|
1556
2066
|
guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
|
|
1557
2067
|
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
|
|
2068
|
+
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`,
|
|
2069
|
+
pollExpire: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/expire`,
|
|
2070
|
+
pollAnswerVoters: (channelId, messageId, answerId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/answers/${integer(answerId, "Answer ID")}`,
|
|
2071
|
+
guildSticker: (guildId, stickerId) => stickerId ? `/guilds/${snowflake(guildId, "Guild ID")}/stickers/${snowflake(stickerId, "Sticker ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/stickers`,
|
|
2072
|
+
sendSoundboardSound: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/send-soundboard-sound`,
|
|
2073
|
+
soundboardDefaultSounds: () => "/soundboard-default-sounds",
|
|
2074
|
+
guildSoundboardSound: (guildId, soundId) => soundId ? `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds/${snowflake(soundId, "Sound ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds`,
|
|
2075
|
+
applicationSkus: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/skus`,
|
|
2076
|
+
applicationEntitlement: (applicationId, entitlementId) => entitlementId ? `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/entitlements`,
|
|
2077
|
+
consumeEntitlement: (applicationId, entitlementId) => `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}/consume`,
|
|
2078
|
+
skuSubscription: (skuId, subscriptionId) => subscriptionId ? `/skus/${snowflake(skuId, "SKU ID")}/subscriptions/${snowflake(subscriptionId, "Subscription ID")}` : `/skus/${snowflake(skuId, "SKU ID")}/subscriptions`
|
|
1559
2079
|
};
|
|
2080
|
+
function integer(value, field) {
|
|
2081
|
+
if (!Number.isInteger(value) || value < 0)
|
|
2082
|
+
throw new TypeError(`${field} must be a non-negative integer.`);
|
|
2083
|
+
return String(value);
|
|
2084
|
+
}
|
|
1560
2085
|
function snowflake(value, field) {
|
|
1561
2086
|
if (!/^\d{1,20}$/.test(value))
|
|
1562
2087
|
throw new TypeError(`${field} must be a valid Discord snowflake.`);
|
|
@@ -1870,7 +2395,8 @@ class REST {
|
|
|
1870
2395
|
throw new RESTError(failure.message, 0, undefined, undefined, {
|
|
1871
2396
|
method,
|
|
1872
2397
|
path,
|
|
1873
|
-
cause: failure.cause ?? failure
|
|
2398
|
+
cause: failure.cause ?? failure,
|
|
2399
|
+
kind: failure.timedOut ? "timeout" : "network"
|
|
1874
2400
|
});
|
|
1875
2401
|
}
|
|
1876
2402
|
this.#emit(this.#hooks.onResponse, {
|
|
@@ -1969,6 +2495,9 @@ class REST {
|
|
|
1969
2495
|
#emit(hook, ctx) {
|
|
1970
2496
|
if (!hook)
|
|
1971
2497
|
return;
|
|
2498
|
+
const withPath = ctx;
|
|
2499
|
+
if (typeof withPath.path === "string")
|
|
2500
|
+
ctx = { ...ctx, path: redactPath(withPath.path) };
|
|
1972
2501
|
Promise.resolve().then(() => hook(ctx)).catch(() => {});
|
|
1973
2502
|
}
|
|
1974
2503
|
}
|
|
@@ -2045,6 +2574,7 @@ class Channel extends BaseStructure {
|
|
|
2045
2574
|
nsfw;
|
|
2046
2575
|
rateLimitPerUser;
|
|
2047
2576
|
position;
|
|
2577
|
+
permissionOverwrites;
|
|
2048
2578
|
#context;
|
|
2049
2579
|
constructor(data, context) {
|
|
2050
2580
|
super(data.id);
|
|
@@ -2058,6 +2588,7 @@ class Channel extends BaseStructure {
|
|
|
2058
2588
|
this.nsfw = data.nsfw;
|
|
2059
2589
|
this.rateLimitPerUser = data.rate_limit_per_user;
|
|
2060
2590
|
this.position = data.position;
|
|
2591
|
+
this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
|
|
2061
2592
|
this.#context = context;
|
|
2062
2593
|
}
|
|
2063
2594
|
sendMessage(options) {
|
|
@@ -2810,6 +3341,17 @@ var InteractionType = {
|
|
|
2810
3341
|
ApplicationCommandAutocomplete: 4,
|
|
2811
3342
|
ModalSubmit: 5
|
|
2812
3343
|
};
|
|
3344
|
+
var EPHEMERAL = 64;
|
|
3345
|
+
var TOKEN_LIFETIME_MS = 15 * 60000;
|
|
3346
|
+
var DISCORD_EPOCH = 1420070400000n;
|
|
3347
|
+
function toMessageData(options) {
|
|
3348
|
+
if (typeof options === "string")
|
|
3349
|
+
return { content: options };
|
|
3350
|
+
const { ephemeral, ...data } = options;
|
|
3351
|
+
if (ephemeral)
|
|
3352
|
+
data.flags = (typeof data.flags === "number" ? data.flags : 0) | EPHEMERAL;
|
|
3353
|
+
return data;
|
|
3354
|
+
}
|
|
2813
3355
|
|
|
2814
3356
|
class InteractionResponse {
|
|
2815
3357
|
type;
|
|
@@ -2824,14 +3366,10 @@ class InteractionResponse {
|
|
|
2824
3366
|
return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
|
|
2825
3367
|
}
|
|
2826
3368
|
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);
|
|
3369
|
+
return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
|
|
2832
3370
|
}
|
|
2833
3371
|
static defer(ephemeral = false) {
|
|
2834
|
-
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags:
|
|
3372
|
+
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
|
|
2835
3373
|
}
|
|
2836
3374
|
static pong() {
|
|
2837
3375
|
return new InteractionResponse(InteractionResponseType.Pong);
|
|
@@ -2849,6 +3387,7 @@ class Interaction {
|
|
|
2849
3387
|
replied = false;
|
|
2850
3388
|
deferred = false;
|
|
2851
3389
|
#client;
|
|
3390
|
+
#acknowledging = false;
|
|
2852
3391
|
constructor(client, data) {
|
|
2853
3392
|
if (!data.id || !data.token)
|
|
2854
3393
|
throw new TypeError("Interaction ID and token are required.");
|
|
@@ -2898,9 +3437,57 @@ class Interaction {
|
|
|
2898
3437
|
return [3, 5, 6, 7, 8].includes(this.#componentType());
|
|
2899
3438
|
}
|
|
2900
3439
|
assertUnacknowledged() {
|
|
2901
|
-
if (this.replied || this.deferred)
|
|
3440
|
+
if (this.replied || this.deferred || this.#acknowledging)
|
|
2902
3441
|
throw new Error("Interaction has already been acknowledged.");
|
|
2903
3442
|
}
|
|
3443
|
+
async acknowledge(response, state) {
|
|
3444
|
+
this.assertUnacknowledged();
|
|
3445
|
+
this.#acknowledging = true;
|
|
3446
|
+
try {
|
|
3447
|
+
const result = await this.postResponse(response);
|
|
3448
|
+
this[state] = true;
|
|
3449
|
+
return result;
|
|
3450
|
+
} finally {
|
|
3451
|
+
this.#acknowledging = false;
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
get user() {
|
|
3455
|
+
const raw = this.data.member?.user ?? this.data.user;
|
|
3456
|
+
return raw ? new User(raw) : null;
|
|
3457
|
+
}
|
|
3458
|
+
get member() {
|
|
3459
|
+
const raw = this.data.member;
|
|
3460
|
+
if (!raw || !this.guildId)
|
|
3461
|
+
return null;
|
|
3462
|
+
return new GuildMember({
|
|
3463
|
+
...raw,
|
|
3464
|
+
guild_id: this.guildId
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3467
|
+
get createdTimestamp() {
|
|
3468
|
+
return Number((BigInt(this.id) >> 22n) + DISCORD_EPOCH);
|
|
3469
|
+
}
|
|
3470
|
+
get expiresAt() {
|
|
3471
|
+
return new Date(this.createdTimestamp + TOKEN_LIFETIME_MS);
|
|
3472
|
+
}
|
|
3473
|
+
get isExpired() {
|
|
3474
|
+
return Date.now() >= this.createdTimestamp + TOKEN_LIFETIME_MS;
|
|
3475
|
+
}
|
|
3476
|
+
#webhookMessage(method, messageId, data) {
|
|
3477
|
+
if (!this.#client.interactionWebhookMessage)
|
|
3478
|
+
return Promise.reject(new Error("This interaction client does not support webhook message access."));
|
|
3479
|
+
return this.#client.interactionWebhookMessage(method, this.applicationId, this.token, messageId, data);
|
|
3480
|
+
}
|
|
3481
|
+
fetchReply() {
|
|
3482
|
+
this.assertAcknowledged();
|
|
3483
|
+
return this.#webhookMessage("GET", "@original");
|
|
3484
|
+
}
|
|
3485
|
+
editFollowUp(messageId, options) {
|
|
3486
|
+
return this.#webhookMessage("PATCH", messageId, toMessageData(options));
|
|
3487
|
+
}
|
|
3488
|
+
async deleteFollowUp(messageId) {
|
|
3489
|
+
await this.#webhookMessage("DELETE", messageId);
|
|
3490
|
+
}
|
|
2904
3491
|
assertAcknowledged() {
|
|
2905
3492
|
if (!this.replied && !this.deferred)
|
|
2906
3493
|
throw new Error("Interaction has not been acknowledged.");
|
|
@@ -2909,41 +3496,27 @@ class Interaction {
|
|
|
2909
3496
|
return this.#client.postInteractionResponse(this.id, this.token, response);
|
|
2910
3497
|
}
|
|
2911
3498
|
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;
|
|
3499
|
+
return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
|
|
2917
3500
|
}
|
|
2918
3501
|
async deferReply(ephemeral = false) {
|
|
2919
|
-
this.
|
|
2920
|
-
await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.defer(ephemeral));
|
|
2921
|
-
this.deferred = true;
|
|
3502
|
+
await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
|
|
2922
3503
|
}
|
|
2923
3504
|
editReply(options) {
|
|
2924
3505
|
this.assertAcknowledged();
|
|
2925
|
-
return this.#client.editInteractionReply(this.token, options);
|
|
3506
|
+
return this.#client.editInteractionReply(this.token, toMessageData(options));
|
|
2926
3507
|
}
|
|
2927
3508
|
deleteReply() {
|
|
2928
3509
|
this.assertAcknowledged();
|
|
2929
3510
|
return this.#client.deleteInteractionReply(this.token);
|
|
2930
3511
|
}
|
|
2931
3512
|
followUp(options) {
|
|
2932
|
-
|
|
2933
|
-
return this.#client.followUpInteraction(this.token, payload);
|
|
3513
|
+
return this.#client.followUpInteraction(this.token, toMessageData(options));
|
|
2934
3514
|
}
|
|
2935
3515
|
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;
|
|
3516
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2941
3517
|
}
|
|
2942
3518
|
async showModal(modal) {
|
|
2943
|
-
this.
|
|
2944
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.Modal, modal));
|
|
2945
|
-
this.replied = true;
|
|
2946
|
-
return result;
|
|
3519
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, modal), "replied");
|
|
2947
3520
|
}
|
|
2948
3521
|
}
|
|
2949
3522
|
|
|
@@ -2971,16 +3544,10 @@ class ComponentInteraction extends Interaction {
|
|
|
2971
3544
|
return this.data?.data?.values ?? [];
|
|
2972
3545
|
}
|
|
2973
3546
|
async deferUpdate() {
|
|
2974
|
-
this.
|
|
2975
|
-
await this.postResponse(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate));
|
|
2976
|
-
this.deferred = true;
|
|
3547
|
+
await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
|
|
2977
3548
|
}
|
|
2978
3549
|
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;
|
|
3550
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2984
3551
|
}
|
|
2985
3552
|
}
|
|
2986
3553
|
|
|
@@ -3023,8 +3590,7 @@ class AutocompleteInteraction extends Interaction {
|
|
|
3023
3590
|
if (!Array.isArray(choices))
|
|
3024
3591
|
throw new TypeError("Autocomplete choices must be an array.");
|
|
3025
3592
|
const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
|
|
3026
|
-
await this.
|
|
3027
|
-
this.replied = true;
|
|
3593
|
+
await this.acknowledge(response, "replied");
|
|
3028
3594
|
}
|
|
3029
3595
|
}
|
|
3030
3596
|
function findFocused(options) {
|
|
@@ -3377,16 +3943,22 @@ class Message extends BaseStructure {
|
|
|
3377
3943
|
|
|
3378
3944
|
// packages/managers/src/message.ts
|
|
3379
3945
|
class MessageManager {
|
|
3380
|
-
cache
|
|
3946
|
+
cache;
|
|
3947
|
+
#caching;
|
|
3381
3948
|
#rest;
|
|
3382
3949
|
#context;
|
|
3383
3950
|
#channelId;
|
|
3384
|
-
constructor(rest, context, channelId) {
|
|
3951
|
+
constructor(rest, context, channelId, cache) {
|
|
3385
3952
|
if (!channelId)
|
|
3386
3953
|
throw new TypeError("Channel ID is required.");
|
|
3387
3954
|
this.#rest = rest;
|
|
3388
3955
|
this.#context = context;
|
|
3389
3956
|
this.#channelId = channelId;
|
|
3957
|
+
this.#caching = cache !== undefined;
|
|
3958
|
+
this.cache = new Collection(null, {
|
|
3959
|
+
ttl: cache?.ttl,
|
|
3960
|
+
maxSize: cache ? cache.maxSize ?? 100 : undefined
|
|
3961
|
+
});
|
|
3390
3962
|
}
|
|
3391
3963
|
async resolve(messageId) {
|
|
3392
3964
|
return this.cache.get(messageId) ?? this.fetch(messageId);
|
|
@@ -3403,13 +3975,14 @@ class MessageManager {
|
|
|
3403
3975
|
return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
|
|
3404
3976
|
}
|
|
3405
3977
|
upsert(data) {
|
|
3406
|
-
const existing = this.cache.
|
|
3978
|
+
const existing = this.cache.peek(data.id);
|
|
3407
3979
|
const message = new Message(data, this.#context);
|
|
3408
3980
|
if (existing) {
|
|
3409
3981
|
Object.assign(existing, message);
|
|
3410
3982
|
return existing;
|
|
3411
3983
|
}
|
|
3412
|
-
this
|
|
3984
|
+
if (this.#caching)
|
|
3985
|
+
this.cache.set(message.id, message);
|
|
3413
3986
|
return message;
|
|
3414
3987
|
}
|
|
3415
3988
|
delete(messageId) {
|
|
@@ -3463,8 +4036,295 @@ class UserManager extends ResourceManager {
|
|
|
3463
4036
|
});
|
|
3464
4037
|
}
|
|
3465
4038
|
}
|
|
4039
|
+
// packages/managers/src/emoji.ts
|
|
4040
|
+
class EmojiManager extends Manager {
|
|
4041
|
+
#rest;
|
|
4042
|
+
#guildId;
|
|
4043
|
+
constructor(rest, guildId) {
|
|
4044
|
+
super();
|
|
4045
|
+
this.#rest = rest;
|
|
4046
|
+
this.#guildId = guildId;
|
|
4047
|
+
}
|
|
4048
|
+
fetch(emojiId) {
|
|
4049
|
+
return this.fetchOnce(emojiId, async () => new Emoji(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId))), (emoji) => this.#merge(emojiId, emoji));
|
|
4050
|
+
}
|
|
4051
|
+
async fetchAll() {
|
|
4052
|
+
const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
|
|
4053
|
+
return data.map((item) => this.upsert(item));
|
|
4054
|
+
}
|
|
4055
|
+
async create(options) {
|
|
4056
|
+
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
|
|
4057
|
+
}
|
|
4058
|
+
async edit(emojiId, options) {
|
|
4059
|
+
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
|
|
4060
|
+
}
|
|
4061
|
+
async deleteEmoji(emojiId) {
|
|
4062
|
+
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
|
|
4063
|
+
this.delete(emojiId);
|
|
4064
|
+
}
|
|
4065
|
+
upsert(data) {
|
|
4066
|
+
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
4067
|
+
return this.#merge(key, new Emoji(data));
|
|
4068
|
+
}
|
|
4069
|
+
#merge(key, emoji) {
|
|
4070
|
+
const existing = this.get(key);
|
|
4071
|
+
if (existing) {
|
|
4072
|
+
Object.assign(existing, emoji);
|
|
4073
|
+
return existing;
|
|
4074
|
+
}
|
|
4075
|
+
this.set(key, emoji);
|
|
4076
|
+
return emoji;
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
|
|
4080
|
+
// packages/managers/src/advanced.ts
|
|
4081
|
+
function withQuery(path, query) {
|
|
4082
|
+
const params = new URLSearchParams;
|
|
4083
|
+
for (const [key, value] of Object.entries(query))
|
|
4084
|
+
if (value !== undefined)
|
|
4085
|
+
params.set(key, String(value));
|
|
4086
|
+
const suffix = params.toString();
|
|
4087
|
+
return suffix ? `${path}?${suffix}` : path;
|
|
4088
|
+
}
|
|
4089
|
+
|
|
4090
|
+
class GuildStickerManager extends Manager {
|
|
4091
|
+
#rest;
|
|
4092
|
+
guildId;
|
|
4093
|
+
constructor(rest, guildId) {
|
|
4094
|
+
super();
|
|
4095
|
+
this.#rest = rest;
|
|
4096
|
+
this.guildId = guildId;
|
|
4097
|
+
}
|
|
4098
|
+
#store(sticker) {
|
|
4099
|
+
this.set(sticker.id, sticker);
|
|
4100
|
+
return sticker;
|
|
4101
|
+
}
|
|
4102
|
+
async fetchAll() {
|
|
4103
|
+
const stickers = await this.#rest.get(Routes.guildSticker(this.guildId));
|
|
4104
|
+
this.clear();
|
|
4105
|
+
return stickers.map((sticker) => this.#store(sticker));
|
|
4106
|
+
}
|
|
4107
|
+
async fetch(stickerId) {
|
|
4108
|
+
return this.#store(await this.#rest.get(Routes.guildSticker(this.guildId, stickerId)));
|
|
4109
|
+
}
|
|
4110
|
+
async create(options) {
|
|
4111
|
+
const form = new FormData;
|
|
4112
|
+
form.set("name", options.name);
|
|
4113
|
+
form.set("description", options.description);
|
|
4114
|
+
form.set("tags", options.tags);
|
|
4115
|
+
form.set("file", options.file);
|
|
4116
|
+
return this.#store(await this.#rest.post(Routes.guildSticker(this.guildId), form, { reason: options.reason }));
|
|
4117
|
+
}
|
|
4118
|
+
async edit(stickerId, options) {
|
|
4119
|
+
const { reason, ...body } = options;
|
|
4120
|
+
return this.#store(await this.#rest.patch(Routes.guildSticker(this.guildId, stickerId), body, { reason }));
|
|
4121
|
+
}
|
|
4122
|
+
async remove(stickerId, reason) {
|
|
4123
|
+
await this.#rest.delete(Routes.guildSticker(this.guildId, stickerId), {
|
|
4124
|
+
reason
|
|
4125
|
+
});
|
|
4126
|
+
this.delete(stickerId);
|
|
4127
|
+
}
|
|
4128
|
+
sync(stickers) {
|
|
4129
|
+
this.clear();
|
|
4130
|
+
for (const sticker of stickers)
|
|
4131
|
+
this.#store(sticker);
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4134
|
+
|
|
4135
|
+
class GuildSoundboardManager extends Manager {
|
|
4136
|
+
#rest;
|
|
4137
|
+
guildId;
|
|
4138
|
+
constructor(rest, guildId) {
|
|
4139
|
+
super();
|
|
4140
|
+
this.#rest = rest;
|
|
4141
|
+
this.guildId = guildId;
|
|
4142
|
+
}
|
|
4143
|
+
#store(sound) {
|
|
4144
|
+
this.set(sound.sound_id, sound);
|
|
4145
|
+
return sound;
|
|
4146
|
+
}
|
|
4147
|
+
async fetchAll() {
|
|
4148
|
+
const { items } = await this.#rest.get(Routes.guildSoundboardSound(this.guildId));
|
|
4149
|
+
this.clear();
|
|
4150
|
+
return items.map((sound) => this.#store(sound));
|
|
4151
|
+
}
|
|
4152
|
+
async fetch(soundId) {
|
|
4153
|
+
return this.#store(await this.#rest.get(Routes.guildSoundboardSound(this.guildId, soundId)));
|
|
4154
|
+
}
|
|
4155
|
+
async create(options) {
|
|
4156
|
+
if (options.volume !== undefined && (options.volume < 0 || options.volume > 1))
|
|
4157
|
+
throw new RangeError("Soundboard volume must be between 0 and 1.");
|
|
4158
|
+
return this.#store(await this.#rest.post(Routes.guildSoundboardSound(this.guildId), {
|
|
4159
|
+
name: options.name,
|
|
4160
|
+
sound: options.sound,
|
|
4161
|
+
volume: options.volume,
|
|
4162
|
+
emoji_id: options.emojiId,
|
|
4163
|
+
emoji_name: options.emojiName
|
|
4164
|
+
}, { reason: options.reason }));
|
|
4165
|
+
}
|
|
4166
|
+
async edit(soundId, options) {
|
|
4167
|
+
return this.#store(await this.#rest.patch(Routes.guildSoundboardSound(this.guildId, soundId), {
|
|
4168
|
+
name: options.name,
|
|
4169
|
+
volume: options.volume,
|
|
4170
|
+
emoji_id: options.emojiId,
|
|
4171
|
+
emoji_name: options.emojiName
|
|
4172
|
+
}, { reason: options.reason }));
|
|
4173
|
+
}
|
|
4174
|
+
async remove(soundId, reason) {
|
|
4175
|
+
await this.#rest.delete(Routes.guildSoundboardSound(this.guildId, soundId), { reason });
|
|
4176
|
+
this.delete(soundId);
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
|
|
4180
|
+
class MonetizationManager extends Manager {
|
|
4181
|
+
#rest;
|
|
4182
|
+
applicationId;
|
|
4183
|
+
constructor(rest, applicationId) {
|
|
4184
|
+
super();
|
|
4185
|
+
this.#rest = rest;
|
|
4186
|
+
this.applicationId = applicationId;
|
|
4187
|
+
}
|
|
4188
|
+
fetchSkus() {
|
|
4189
|
+
return this.#rest.get(Routes.applicationSkus(this.applicationId));
|
|
4190
|
+
}
|
|
4191
|
+
async fetchEntitlements(query = {}) {
|
|
4192
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 100))
|
|
4193
|
+
throw new RangeError("Entitlement limit must be 1-100.");
|
|
4194
|
+
const entitlements = await this.#rest.get(withQuery(Routes.applicationEntitlement(this.applicationId), {
|
|
4195
|
+
user_id: query.userId,
|
|
4196
|
+
sku_ids: query.skuIds?.join(","),
|
|
4197
|
+
guild_id: query.guildId,
|
|
4198
|
+
before: query.before,
|
|
4199
|
+
after: query.after,
|
|
4200
|
+
limit: query.limit,
|
|
4201
|
+
exclude_ended: query.excludeEnded,
|
|
4202
|
+
exclude_deleted: query.excludeDeleted
|
|
4203
|
+
}));
|
|
4204
|
+
for (const entitlement of entitlements)
|
|
4205
|
+
this.set(entitlement.id, entitlement);
|
|
4206
|
+
return entitlements;
|
|
4207
|
+
}
|
|
4208
|
+
async fetch(entitlementId) {
|
|
4209
|
+
const entitlement = await this.#rest.get(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
4210
|
+
this.set(entitlement.id, entitlement);
|
|
4211
|
+
return entitlement;
|
|
4212
|
+
}
|
|
4213
|
+
async consume(entitlementId) {
|
|
4214
|
+
await this.#rest.post(Routes.consumeEntitlement(this.applicationId, entitlementId));
|
|
4215
|
+
const cached = this.get(entitlementId);
|
|
4216
|
+
if (cached)
|
|
4217
|
+
cached.consumed = true;
|
|
4218
|
+
}
|
|
4219
|
+
async createTestEntitlement(options) {
|
|
4220
|
+
const entitlement = await this.#rest.post(Routes.applicationEntitlement(this.applicationId), {
|
|
4221
|
+
sku_id: options.skuId,
|
|
4222
|
+
owner_id: options.ownerId,
|
|
4223
|
+
owner_type: options.ownerType
|
|
4224
|
+
});
|
|
4225
|
+
this.set(entitlement.id, entitlement);
|
|
4226
|
+
return entitlement;
|
|
4227
|
+
}
|
|
4228
|
+
async deleteTestEntitlement(entitlementId) {
|
|
4229
|
+
await this.#rest.delete(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
4230
|
+
this.delete(entitlementId);
|
|
4231
|
+
}
|
|
4232
|
+
fetchSubscriptions(skuId, query = {}) {
|
|
4233
|
+
return this.#rest.get(withQuery(Routes.skuSubscription(skuId), {
|
|
4234
|
+
user_id: query.userId,
|
|
4235
|
+
before: query.before,
|
|
4236
|
+
after: query.after,
|
|
4237
|
+
limit: query.limit
|
|
4238
|
+
}));
|
|
4239
|
+
}
|
|
4240
|
+
fetchSubscription(skuId, subscriptionId) {
|
|
4241
|
+
return this.#rest.get(Routes.skuSubscription(skuId, subscriptionId));
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
// packages/managers/src/member.ts
|
|
4246
|
+
class GuildMemberManager extends ResourceManager {
|
|
4247
|
+
#rest;
|
|
4248
|
+
guildId;
|
|
4249
|
+
constructor(guildId, rest) {
|
|
4250
|
+
super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId })), (member) => member.user.id);
|
|
4251
|
+
this.guildId = guildId;
|
|
4252
|
+
this.#rest = rest;
|
|
4253
|
+
}
|
|
4254
|
+
async kick(userId) {
|
|
4255
|
+
await this.#rest.delete(Routes.guildMember(this.guildId, userId));
|
|
4256
|
+
this.delete(userId);
|
|
4257
|
+
}
|
|
4258
|
+
async ban(userId, options = {}) {
|
|
4259
|
+
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
4260
|
+
this.delete(userId);
|
|
4261
|
+
}
|
|
4262
|
+
async unban(userId) {
|
|
4263
|
+
await this.#rest.delete(Routes.guildBan(this.guildId, userId));
|
|
4264
|
+
}
|
|
4265
|
+
async edit(userId, options) {
|
|
4266
|
+
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options);
|
|
4267
|
+
const member = new GuildMember({ ...data, guild_id: this.guildId });
|
|
4268
|
+
this.set(member.user.id, member);
|
|
4269
|
+
return member;
|
|
4270
|
+
}
|
|
4271
|
+
async addRole(userId, roleId) {
|
|
4272
|
+
await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
4273
|
+
}
|
|
4274
|
+
async removeRole(userId, roleId) {
|
|
4275
|
+
await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
4276
|
+
}
|
|
4277
|
+
async timeout(userId, milliseconds) {
|
|
4278
|
+
const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
|
|
4279
|
+
return this.edit(userId, { communication_disabled_until: timeoutDate });
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
|
|
4283
|
+
// packages/managers/src/role.ts
|
|
4284
|
+
class RoleManager extends ResourceManager {
|
|
4285
|
+
#rest;
|
|
4286
|
+
guildId;
|
|
4287
|
+
constructor(guildId, rest) {
|
|
4288
|
+
super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
|
|
4289
|
+
this.guildId = guildId;
|
|
4290
|
+
this.#rest = rest;
|
|
4291
|
+
}
|
|
4292
|
+
async fetchAll() {
|
|
4293
|
+
const data = await this.#rest.get(Routes.guildRoles(this.guildId));
|
|
4294
|
+
return data.map((item) => {
|
|
4295
|
+
const role = new Role(item);
|
|
4296
|
+
this.set(role.id, role);
|
|
4297
|
+
return role;
|
|
4298
|
+
});
|
|
4299
|
+
}
|
|
4300
|
+
async create(options) {
|
|
4301
|
+
const { reason, ...payload } = options;
|
|
4302
|
+
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
4303
|
+
...payload,
|
|
4304
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
4305
|
+
});
|
|
4306
|
+
const role = new Role(data);
|
|
4307
|
+
this.set(role.id, role);
|
|
4308
|
+
return role;
|
|
4309
|
+
}
|
|
4310
|
+
async edit(roleId, options) {
|
|
4311
|
+
const { reason, ...payload } = options;
|
|
4312
|
+
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
4313
|
+
...payload,
|
|
4314
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
4315
|
+
});
|
|
4316
|
+
const role = new Role(data);
|
|
4317
|
+
this.set(role.id, role);
|
|
4318
|
+
return role;
|
|
4319
|
+
}
|
|
4320
|
+
async deleteRole(roleId) {
|
|
4321
|
+
await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
|
|
4322
|
+
this.delete(roleId);
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
|
|
3466
4326
|
// packages/managers/src/guild-resources.ts
|
|
3467
|
-
function
|
|
4327
|
+
function withQuery2(path, params) {
|
|
3468
4328
|
const query = new URLSearchParams;
|
|
3469
4329
|
for (const [key, value] of Object.entries(params))
|
|
3470
4330
|
if (value !== undefined)
|
|
@@ -3488,7 +4348,7 @@ class GuildBanManager extends Manager {
|
|
|
3488
4348
|
}
|
|
3489
4349
|
async fetchAll(options = {}) {
|
|
3490
4350
|
const limit = options.limit === undefined ? undefined : Math.min(1000, Math.max(1, options.limit));
|
|
3491
|
-
const bans = await this.#rest.get(
|
|
4351
|
+
const bans = await this.#rest.get(withQuery2(Routes.guildBans(this.guildId), {
|
|
3492
4352
|
limit,
|
|
3493
4353
|
before: options.before,
|
|
3494
4354
|
after: options.after
|
|
@@ -3521,12 +4381,12 @@ class GuildScheduledEventManager extends Manager {
|
|
|
3521
4381
|
return event;
|
|
3522
4382
|
}
|
|
3523
4383
|
async fetch(eventId, options = {}) {
|
|
3524
|
-
return this.#store(await this.#rest.get(
|
|
4384
|
+
return this.#store(await this.#rest.get(withQuery2(Routes.guildScheduledEvent(this.guildId, eventId), {
|
|
3525
4385
|
with_user_count: options.withUserCount
|
|
3526
4386
|
})));
|
|
3527
4387
|
}
|
|
3528
4388
|
async fetchAll(options = {}) {
|
|
3529
|
-
const events = await this.#rest.get(
|
|
4389
|
+
const events = await this.#rest.get(withQuery2(Routes.guildScheduledEvents(this.guildId), {
|
|
3530
4390
|
with_user_count: options.withUserCount
|
|
3531
4391
|
}));
|
|
3532
4392
|
return events.map((event) => this.#store(event));
|
|
@@ -3543,7 +4403,7 @@ class GuildScheduledEventManager extends Manager {
|
|
|
3543
4403
|
}
|
|
3544
4404
|
async fetchSubscribers(eventId, options = {}) {
|
|
3545
4405
|
const limit = options.limit === undefined ? undefined : Math.min(100, Math.max(1, options.limit));
|
|
3546
|
-
return this.#rest.get(
|
|
4406
|
+
return this.#rest.get(withQuery2(Routes.guildScheduledEventUsers(this.guildId, eventId), {
|
|
3547
4407
|
limit,
|
|
3548
4408
|
with_member: options.withMember,
|
|
3549
4409
|
before: options.before,
|
|
@@ -3605,7 +4465,7 @@ class PermissionOverwriteManager {
|
|
|
3605
4465
|
}
|
|
3606
4466
|
|
|
3607
4467
|
// packages/managers/src/guild.ts
|
|
3608
|
-
function
|
|
4468
|
+
function withQuery3(path, params) {
|
|
3609
4469
|
const suffix = params.toString();
|
|
3610
4470
|
return suffix ? `${path}?${suffix}` : path;
|
|
3611
4471
|
}
|
|
@@ -3614,22 +4474,98 @@ class GuildManager extends ResourceManager {
|
|
|
3614
4474
|
#rest;
|
|
3615
4475
|
#bans = new Map;
|
|
3616
4476
|
#scheduledEvents = new Map;
|
|
4477
|
+
#members = new Map;
|
|
4478
|
+
#roles = new Map;
|
|
4479
|
+
#emojis = new Map;
|
|
4480
|
+
#stickers = new Map;
|
|
4481
|
+
#soundboard = new Map;
|
|
4482
|
+
#voiceStates = new Map;
|
|
4483
|
+
#autoModerationRules = new Map;
|
|
4484
|
+
#invites = new Map;
|
|
4485
|
+
#perGuild(map, guildId, create) {
|
|
4486
|
+
let manager = map.get(guildId);
|
|
4487
|
+
if (!manager)
|
|
4488
|
+
map.set(guildId, manager = create());
|
|
4489
|
+
return manager;
|
|
4490
|
+
}
|
|
3617
4491
|
constructor(rest) {
|
|
3618
4492
|
super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
|
|
3619
4493
|
this.#rest = rest;
|
|
3620
4494
|
}
|
|
3621
|
-
bans(guildId) {
|
|
3622
|
-
let manager = this.#bans.get(guildId);
|
|
4495
|
+
bans(guildId) {
|
|
4496
|
+
let manager = this.#bans.get(guildId);
|
|
4497
|
+
if (!manager)
|
|
4498
|
+
this.#bans.set(guildId, manager = new GuildBanManager(this.#rest, guildId));
|
|
4499
|
+
return manager;
|
|
4500
|
+
}
|
|
4501
|
+
scheduledEvents(guildId) {
|
|
4502
|
+
let manager = this.#scheduledEvents.get(guildId);
|
|
4503
|
+
if (!manager)
|
|
4504
|
+
this.#scheduledEvents.set(guildId, manager = new GuildScheduledEventManager(this.#rest, guildId));
|
|
4505
|
+
return manager;
|
|
4506
|
+
}
|
|
4507
|
+
members(guildId) {
|
|
4508
|
+
let manager = this.#members.get(guildId);
|
|
4509
|
+
if (!manager)
|
|
4510
|
+
this.#members.set(guildId, manager = new GuildMemberManager(guildId, this.#rest));
|
|
4511
|
+
return manager;
|
|
4512
|
+
}
|
|
4513
|
+
roles(guildId) {
|
|
4514
|
+
let manager = this.#roles.get(guildId);
|
|
3623
4515
|
if (!manager)
|
|
3624
|
-
this.#
|
|
4516
|
+
this.#roles.set(guildId, manager = new RoleManager(guildId, this.#rest));
|
|
3625
4517
|
return manager;
|
|
3626
4518
|
}
|
|
3627
|
-
|
|
3628
|
-
let manager = this.#
|
|
4519
|
+
emojis(guildId) {
|
|
4520
|
+
let manager = this.#emojis.get(guildId);
|
|
3629
4521
|
if (!manager)
|
|
3630
|
-
this.#
|
|
4522
|
+
this.#emojis.set(guildId, manager = new EmojiManager(this.#rest, guildId));
|
|
3631
4523
|
return manager;
|
|
3632
4524
|
}
|
|
4525
|
+
stickers(guildId) {
|
|
4526
|
+
let manager = this.#stickers.get(guildId);
|
|
4527
|
+
if (!manager)
|
|
4528
|
+
this.#stickers.set(guildId, manager = new GuildStickerManager(this.#rest, guildId));
|
|
4529
|
+
return manager;
|
|
4530
|
+
}
|
|
4531
|
+
soundboard(guildId) {
|
|
4532
|
+
let manager = this.#soundboard.get(guildId);
|
|
4533
|
+
if (!manager)
|
|
4534
|
+
this.#soundboard.set(guildId, manager = new GuildSoundboardManager(this.#rest, guildId));
|
|
4535
|
+
return manager;
|
|
4536
|
+
}
|
|
4537
|
+
voiceStates(guildId) {
|
|
4538
|
+
return this.#perGuild(this.#voiceStates, guildId, () => new Manager);
|
|
4539
|
+
}
|
|
4540
|
+
autoModerationRules(guildId) {
|
|
4541
|
+
return this.#perGuild(this.#autoModerationRules, guildId, () => new Manager);
|
|
4542
|
+
}
|
|
4543
|
+
invites(guildId) {
|
|
4544
|
+
return this.#perGuild(this.#invites, guildId, () => new Manager);
|
|
4545
|
+
}
|
|
4546
|
+
patch(data) {
|
|
4547
|
+
const guild = new Guild(data);
|
|
4548
|
+
const existing = this.get(guild.id);
|
|
4549
|
+
if (!existing)
|
|
4550
|
+
return this.upsert(guild);
|
|
4551
|
+
for (const [key, value] of Object.entries(guild))
|
|
4552
|
+
if (value !== undefined)
|
|
4553
|
+
existing[key] = value;
|
|
4554
|
+
return existing;
|
|
4555
|
+
}
|
|
4556
|
+
delete(id) {
|
|
4557
|
+
this.#bans.delete(id);
|
|
4558
|
+
this.#scheduledEvents.delete(id);
|
|
4559
|
+
this.#members.delete(id);
|
|
4560
|
+
this.#roles.delete(id);
|
|
4561
|
+
this.#emojis.delete(id);
|
|
4562
|
+
this.#stickers.delete(id);
|
|
4563
|
+
this.#soundboard.delete(id);
|
|
4564
|
+
this.#voiceStates.delete(id);
|
|
4565
|
+
this.#autoModerationRules.delete(id);
|
|
4566
|
+
this.#invites.delete(id);
|
|
4567
|
+
return super.delete(id);
|
|
4568
|
+
}
|
|
3633
4569
|
async create(options) {
|
|
3634
4570
|
const data = await this.#rest.post("/guilds", options);
|
|
3635
4571
|
return this.upsert(new Guild(data));
|
|
@@ -3665,7 +4601,7 @@ class GuildManager extends ResourceManager {
|
|
|
3665
4601
|
params.set("after", options.after);
|
|
3666
4602
|
if (options.limit !== undefined)
|
|
3667
4603
|
params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
|
|
3668
|
-
return this.#rest.get(
|
|
4604
|
+
return this.#rest.get(withQuery3(Routes.guildAuditLog(guildId), params));
|
|
3669
4605
|
}
|
|
3670
4606
|
async fetchMembers(guildId, options = {}) {
|
|
3671
4607
|
const params = new URLSearchParams;
|
|
@@ -3673,7 +4609,7 @@ class GuildManager extends ResourceManager {
|
|
|
3673
4609
|
params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
|
|
3674
4610
|
if (options.after)
|
|
3675
4611
|
params.set("after", options.after);
|
|
3676
|
-
return this.#rest.get(
|
|
4612
|
+
return this.#rest.get(withQuery3(Routes.guildMembers(guildId), params));
|
|
3677
4613
|
}
|
|
3678
4614
|
async fetchAutoModerationRules(guildId) {
|
|
3679
4615
|
const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
|
|
@@ -3748,85 +4684,6 @@ var AuditLogEvent = {
|
|
|
3748
4684
|
AutoModerationRuleDelete: 142,
|
|
3749
4685
|
AutoModerationBlockMessage: 143
|
|
3750
4686
|
};
|
|
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;
|
|
3818
|
-
}
|
|
3819
|
-
async addRole(userId, roleId) {
|
|
3820
|
-
await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
3821
|
-
}
|
|
3822
|
-
async removeRole(userId, roleId) {
|
|
3823
|
-
await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
3824
|
-
}
|
|
3825
|
-
async timeout(userId, milliseconds) {
|
|
3826
|
-
const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
|
|
3827
|
-
return this.edit(userId, { communication_disabled_until: timeoutDate });
|
|
3828
|
-
}
|
|
3829
|
-
}
|
|
3830
4687
|
// packages/managers/src/application.ts
|
|
3831
4688
|
class ApplicationCommandManager {
|
|
3832
4689
|
#rest;
|
|
@@ -3866,53 +4723,22 @@ class ApplicationCommandManager {
|
|
|
3866
4723
|
await this.#rest.delete(Routes.guildApplicationCommand(this.#applicationId, guildId, commandId));
|
|
3867
4724
|
}
|
|
3868
4725
|
}
|
|
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
4726
|
|
|
3908
4727
|
// packages/managers/src/index.ts
|
|
4728
|
+
var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
|
|
4729
|
+
function snowflakeTime(id) {
|
|
4730
|
+
return Number((BigInt(id) >> 22n) + 1420070400000n);
|
|
4731
|
+
}
|
|
4732
|
+
|
|
3909
4733
|
class ChannelManager extends Manager {
|
|
3910
4734
|
#rest;
|
|
3911
4735
|
#context;
|
|
3912
4736
|
#messageManagers = new Map;
|
|
3913
|
-
|
|
4737
|
+
#messageCache;
|
|
4738
|
+
constructor(rest, options = {}) {
|
|
3914
4739
|
super();
|
|
3915
4740
|
this.#rest = rest;
|
|
4741
|
+
this.#messageCache = options.messageCache;
|
|
3916
4742
|
this.#context = {
|
|
3917
4743
|
sendMessage: (channelId, options) => this.send(channelId, options),
|
|
3918
4744
|
editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
|
|
@@ -3931,7 +4757,7 @@ class ChannelManager extends Manager {
|
|
|
3931
4757
|
messages(channelId) {
|
|
3932
4758
|
let manager = this.#messageManagers.get(channelId);
|
|
3933
4759
|
if (!manager) {
|
|
3934
|
-
manager = new MessageManager(this.#rest, this.#context, channelId);
|
|
4760
|
+
manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
|
|
3935
4761
|
this.#messageManagers.set(channelId, manager);
|
|
3936
4762
|
}
|
|
3937
4763
|
return manager;
|
|
@@ -3942,16 +4768,18 @@ class ChannelManager extends Manager {
|
|
|
3942
4768
|
threads(channelId) {
|
|
3943
4769
|
return new ThreadManager(this.#rest, this.#context, channelId);
|
|
3944
4770
|
}
|
|
3945
|
-
|
|
3946
|
-
return this.
|
|
4771
|
+
fetch(channelId) {
|
|
4772
|
+
return this.fetchOnce(channelId, async () => createChannel(await this.#rest.get(Routes.channel(channelId)), this.#context), (channel) => this.#merge(channel));
|
|
3947
4773
|
}
|
|
3948
4774
|
async resolve(channelId) {
|
|
3949
4775
|
return this.get(channelId) ?? this.fetch(channelId);
|
|
3950
4776
|
}
|
|
3951
4777
|
upsert(data) {
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
4778
|
+
return this.#merge(createChannel(data, this.#context));
|
|
4779
|
+
}
|
|
4780
|
+
#merge(channel) {
|
|
4781
|
+
const existing = this.get(channel.id);
|
|
4782
|
+
if (existing && existing.type === channel.type) {
|
|
3955
4783
|
Object.assign(existing, channel);
|
|
3956
4784
|
return existing;
|
|
3957
4785
|
}
|
|
@@ -3961,6 +4789,37 @@ class ChannelManager extends Manager {
|
|
|
3961
4789
|
update(channel) {
|
|
3962
4790
|
return this.set(channel.id, channel);
|
|
3963
4791
|
}
|
|
4792
|
+
deleteGuildChannels(guildId) {
|
|
4793
|
+
let removed = 0;
|
|
4794
|
+
for (const channel of this.values())
|
|
4795
|
+
if (channel.guildId === guildId && this.delete(channel.id))
|
|
4796
|
+
removed++;
|
|
4797
|
+
return removed;
|
|
4798
|
+
}
|
|
4799
|
+
async endPoll(channelId, messageId) {
|
|
4800
|
+
return this.messages(channelId).upsert(await this.#rest.post(Routes.pollExpire(channelId, messageId)));
|
|
4801
|
+
}
|
|
4802
|
+
async fetchPollVoters(channelId, messageId, answerId, options = {}) {
|
|
4803
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100))
|
|
4804
|
+
throw new RangeError("Poll voter limit must be 1-100.");
|
|
4805
|
+
const params = new URLSearchParams;
|
|
4806
|
+
if (options.after)
|
|
4807
|
+
params.set("after", options.after);
|
|
4808
|
+
if (options.limit !== undefined)
|
|
4809
|
+
params.set("limit", String(options.limit));
|
|
4810
|
+
const suffix = params.toString();
|
|
4811
|
+
const { users } = await this.#rest.get(`${Routes.pollAnswerVoters(channelId, messageId, answerId)}${suffix ? `?${suffix}` : ""}`);
|
|
4812
|
+
return users.map((user) => new User(user));
|
|
4813
|
+
}
|
|
4814
|
+
async sendSoundboardSound(channelId, options) {
|
|
4815
|
+
await this.#rest.post(Routes.sendSoundboardSound(channelId), {
|
|
4816
|
+
sound_id: options.soundId,
|
|
4817
|
+
source_guild_id: options.sourceGuildId
|
|
4818
|
+
});
|
|
4819
|
+
}
|
|
4820
|
+
cachedMessages(channelId) {
|
|
4821
|
+
return this.#messageManagers.get(channelId);
|
|
4822
|
+
}
|
|
3964
4823
|
async create(guildId, options) {
|
|
3965
4824
|
return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
|
|
3966
4825
|
}
|
|
@@ -4017,15 +4876,37 @@ class ChannelManager extends Manager {
|
|
|
4017
4876
|
return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
|
|
4018
4877
|
}
|
|
4019
4878
|
async bulkDeleteMessages(channelId, messageIds) {
|
|
4020
|
-
const ids = [...messageIds];
|
|
4021
|
-
if (ids.length <
|
|
4022
|
-
throw new RangeError("bulkDelete requires between
|
|
4879
|
+
const ids = [...new Set(messageIds)];
|
|
4880
|
+
if (ids.length < 1 || ids.length > 100)
|
|
4881
|
+
throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
|
|
4882
|
+
if (ids.length === 1)
|
|
4883
|
+
return this.deleteMessage(channelId, ids[0]);
|
|
4884
|
+
const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
|
|
4885
|
+
const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
|
|
4886
|
+
if (tooOld.length)
|
|
4887
|
+
throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
|
|
4023
4888
|
await this.#rest.post(Routes.channelBulkDelete(channelId), {
|
|
4024
4889
|
messages: ids
|
|
4025
4890
|
});
|
|
4026
4891
|
for (const id of ids)
|
|
4027
4892
|
this.messages(channelId).delete(id);
|
|
4028
4893
|
}
|
|
4894
|
+
async* iterateMessages(channelId, options = {}) {
|
|
4895
|
+
let before = options.before;
|
|
4896
|
+
let remaining = options.limit ?? Infinity;
|
|
4897
|
+
while (remaining > 0) {
|
|
4898
|
+
const page = await this.fetchMessages(channelId, {
|
|
4899
|
+
before,
|
|
4900
|
+
limit: Math.min(100, remaining)
|
|
4901
|
+
});
|
|
4902
|
+
for (const message of page)
|
|
4903
|
+
yield message;
|
|
4904
|
+
remaining -= page.length;
|
|
4905
|
+
if (page.length < 100)
|
|
4906
|
+
return;
|
|
4907
|
+
before = page.at(-1).id;
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4029
4910
|
async addReaction(channelId, messageId, emoji) {
|
|
4030
4911
|
await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
|
|
4031
4912
|
}
|
|
@@ -4121,6 +5002,8 @@ class GatewaySession {
|
|
|
4121
5002
|
return false;
|
|
4122
5003
|
if (!Number.isInteger(sequence))
|
|
4123
5004
|
return false;
|
|
5005
|
+
if (this.#sequence !== null && sequence < this.#sequence)
|
|
5006
|
+
return false;
|
|
4124
5007
|
this.#sequence = sequence;
|
|
4125
5008
|
return true;
|
|
4126
5009
|
}
|
|
@@ -4219,8 +5102,11 @@ class GatewayHeartbeat {
|
|
|
4219
5102
|
this.#clearBeatTimers();
|
|
4220
5103
|
this.#interval = interval;
|
|
4221
5104
|
this.#acknowledged = true;
|
|
4222
|
-
this.#initialTimer = setTimeout(() =>
|
|
4223
|
-
|
|
5105
|
+
this.#initialTimer = setTimeout(() => {
|
|
5106
|
+
this.#initialTimer = undefined;
|
|
5107
|
+
this.sendHeartbeat();
|
|
5108
|
+
this.#timer = setInterval(() => this.sendHeartbeat(), interval);
|
|
5109
|
+
}, Math.random() * interval);
|
|
4224
5110
|
}
|
|
4225
5111
|
stop() {
|
|
4226
5112
|
this.#clearBeatTimers();
|
|
@@ -4246,6 +5132,8 @@ class GatewayHeartbeat {
|
|
|
4246
5132
|
}, this.#options.ackTimeout);
|
|
4247
5133
|
}
|
|
4248
5134
|
acknowledge() {
|
|
5135
|
+
if (this.#acknowledged)
|
|
5136
|
+
return;
|
|
4249
5137
|
this.#acknowledged = true;
|
|
4250
5138
|
this.#latency = this.#now() - this.#sentAt;
|
|
4251
5139
|
this.#clearAckTimer();
|
|
@@ -4826,6 +5714,7 @@ class SendBudget {
|
|
|
4826
5714
|
}
|
|
4827
5715
|
|
|
4828
5716
|
// packages/ws/src/index.ts
|
|
5717
|
+
var RESUMABLE_CLOSE_CODE = 4900;
|
|
4829
5718
|
var DEFAULT_GATEWAY_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
4830
5719
|
|
|
4831
5720
|
class Gateway {
|
|
@@ -4911,7 +5800,7 @@ class Gateway {
|
|
|
4911
5800
|
} else {
|
|
4912
5801
|
this.#emitError(new GatewayError(`Gateway heartbeat acknowledgement timed out after ${timeout.elapsedMs}ms.`));
|
|
4913
5802
|
}
|
|
4914
|
-
this.#transport.close(
|
|
5803
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, timeout.type === "zombie" ? "Zombie Gateway connection" : "Heartbeat timeout");
|
|
4915
5804
|
}
|
|
4916
5805
|
connect(url = DEFAULT_GATEWAY_URL) {
|
|
4917
5806
|
if (this.state === "CLOSED" /* Closed */)
|
|
@@ -5047,7 +5936,7 @@ class Gateway {
|
|
|
5047
5936
|
this.#emit("heartbeatAck", action.data);
|
|
5048
5937
|
return;
|
|
5049
5938
|
case "reconnect":
|
|
5050
|
-
this.#transport.close(
|
|
5939
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, "Server requested reconnect");
|
|
5051
5940
|
return;
|
|
5052
5941
|
case "invalid-session": {
|
|
5053
5942
|
if (!action.resumable)
|
|
@@ -5241,6 +6130,7 @@ class Client extends EventEmitter2 {
|
|
|
5241
6130
|
channels;
|
|
5242
6131
|
stageInstances;
|
|
5243
6132
|
application;
|
|
6133
|
+
monetization;
|
|
5244
6134
|
get ws() {
|
|
5245
6135
|
return this.#gateway;
|
|
5246
6136
|
}
|
|
@@ -5272,6 +6162,7 @@ class Client extends EventEmitter2 {
|
|
|
5272
6162
|
return this.#gateway.requestGuildMembers(data);
|
|
5273
6163
|
}
|
|
5274
6164
|
#gateway;
|
|
6165
|
+
#cache;
|
|
5275
6166
|
#resourceContext;
|
|
5276
6167
|
constructor(options) {
|
|
5277
6168
|
super();
|
|
@@ -5279,9 +6170,18 @@ class Client extends EventEmitter2 {
|
|
|
5279
6170
|
if (!options.token?.trim())
|
|
5280
6171
|
throw new TypeError("Client token is required.");
|
|
5281
6172
|
this.rest = new REST({ token: options.token, ...options.rest });
|
|
6173
|
+
this.#cache = {
|
|
6174
|
+
users: true,
|
|
6175
|
+
members: true,
|
|
6176
|
+
roles: true,
|
|
6177
|
+
emojis: true,
|
|
6178
|
+
...options.cache
|
|
6179
|
+
};
|
|
5282
6180
|
this.users = new UserManager(this.rest);
|
|
5283
6181
|
this.guilds = new GuildManager(this.rest);
|
|
5284
|
-
this.channels = new ChannelManager(this.rest
|
|
6182
|
+
this.channels = new ChannelManager(this.rest, {
|
|
6183
|
+
messageCache: options.messageCache
|
|
6184
|
+
});
|
|
5285
6185
|
this.stageInstances = new StageInstanceManager(this.rest);
|
|
5286
6186
|
const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
|
|
5287
6187
|
this.application = { commands: placeholderAppCommands };
|
|
@@ -5312,6 +6212,8 @@ class Client extends EventEmitter2 {
|
|
|
5312
6212
|
this.state = "ready";
|
|
5313
6213
|
const appId = ready.application?.id ?? this.user.id;
|
|
5314
6214
|
this.application.commands = new ApplicationCommandManager(this.rest, appId);
|
|
6215
|
+
if (this.monetization?.applicationId !== appId)
|
|
6216
|
+
this.monetization = new MonetizationManager(this.rest, appId);
|
|
5315
6217
|
this.emit("ready" /* Ready */, this.user);
|
|
5316
6218
|
});
|
|
5317
6219
|
this.#gateway.on("RESUMED", () => {
|
|
@@ -5329,18 +6231,39 @@ class Client extends EventEmitter2 {
|
|
|
5329
6231
|
});
|
|
5330
6232
|
this.#gateway.on("MESSAGE_CREATE", (data) => {
|
|
5331
6233
|
const message = new Message(data, this.#resourceContext);
|
|
5332
|
-
this
|
|
5333
|
-
this.
|
|
5334
|
-
this.emit("messageCreate" /* MessageCreate */,
|
|
6234
|
+
this.#observeMessage(message);
|
|
6235
|
+
const cached = this.options.messageCache ? this.channels.messages(message.channelId).upsert(data) : message;
|
|
6236
|
+
this.emit("messageCreate" /* MessageCreate */, cached);
|
|
5335
6237
|
});
|
|
5336
6238
|
this.#gateway.on("MESSAGE_UPDATE", (data) => {
|
|
5337
6239
|
const message = new Message(data, this.#resourceContext);
|
|
5338
|
-
this
|
|
5339
|
-
this.
|
|
5340
|
-
|
|
6240
|
+
this.#observeMessage(message);
|
|
6241
|
+
const messages = this.channels.cachedMessages(message.channelId);
|
|
6242
|
+
const previous = messages?.cache.peek(message.id);
|
|
6243
|
+
if (previous)
|
|
6244
|
+
messages.cache.set(message.id, message);
|
|
6245
|
+
this.emit("messageUpdate" /* MessageUpdate */, message, previous);
|
|
6246
|
+
});
|
|
6247
|
+
this.#gateway.on("MESSAGE_DELETE", (data) => {
|
|
6248
|
+
const payload = data;
|
|
6249
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
6250
|
+
const removed = messages?.cache.peek(payload.id);
|
|
6251
|
+
messages?.delete(payload.id);
|
|
6252
|
+
this.emit("messageDelete" /* MessageDelete */, payload, removed);
|
|
6253
|
+
});
|
|
6254
|
+
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => {
|
|
6255
|
+
const payload = data;
|
|
6256
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
6257
|
+
const removed = [];
|
|
6258
|
+
if (messages)
|
|
6259
|
+
for (const id of payload.ids) {
|
|
6260
|
+
const message = messages.cache.peek(id);
|
|
6261
|
+
if (message)
|
|
6262
|
+
removed.push(message);
|
|
6263
|
+
messages.delete(id);
|
|
6264
|
+
}
|
|
6265
|
+
this.emit("messageDeleteBulk" /* MessageDeleteBulk */, payload, removed);
|
|
5341
6266
|
});
|
|
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
6267
|
this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
|
|
5345
6268
|
this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
|
|
5346
6269
|
this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
|
|
@@ -5354,20 +6277,27 @@ class Client extends EventEmitter2 {
|
|
|
5354
6277
|
return;
|
|
5355
6278
|
}
|
|
5356
6279
|
const wasCached = this.guilds.has(payload.id);
|
|
5357
|
-
|
|
5358
|
-
|
|
6280
|
+
this.guilds.patch(payload);
|
|
6281
|
+
for (const role of payload.roles ?? [])
|
|
6282
|
+
this.#upsertRole(payload.id, role);
|
|
6283
|
+
if (this.#cache.emojis) {
|
|
6284
|
+
const emojis = this.guilds.emojis(payload.id);
|
|
6285
|
+
for (const emoji of payload.emojis ?? [])
|
|
6286
|
+
emojis.upsert(emoji);
|
|
6287
|
+
}
|
|
5359
6288
|
for (const member of payload.members ?? [])
|
|
5360
|
-
this
|
|
6289
|
+
this.#upsertMember(payload.id, member);
|
|
6290
|
+
for (const state of payload.voice_states ?? [])
|
|
6291
|
+
this.#storeVoiceState(payload.id, state);
|
|
5361
6292
|
for (const channelData of [
|
|
5362
6293
|
...payload.channels ?? [],
|
|
5363
6294
|
...payload.threads ?? []
|
|
5364
6295
|
])
|
|
5365
|
-
this.channels.
|
|
6296
|
+
this.channels.upsert({ ...channelData, guild_id: payload.id });
|
|
5366
6297
|
this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
|
|
5367
6298
|
});
|
|
5368
6299
|
this.#gateway.on("GUILD_UPDATE", (data) => {
|
|
5369
|
-
|
|
5370
|
-
this.guilds.update(guild);
|
|
6300
|
+
this.guilds.patch(data);
|
|
5371
6301
|
this.emit("guildUpdate" /* GuildUpdate */, data);
|
|
5372
6302
|
});
|
|
5373
6303
|
this.#gateway.on("GUILD_DELETE", (data) => {
|
|
@@ -5377,45 +6307,158 @@ class Client extends EventEmitter2 {
|
|
|
5377
6307
|
return;
|
|
5378
6308
|
}
|
|
5379
6309
|
this.guilds.delete(payload.id);
|
|
6310
|
+
this.channels.deleteGuildChannels(payload.id);
|
|
5380
6311
|
this.emit("guildDelete" /* GuildDelete */, payload);
|
|
5381
6312
|
});
|
|
5382
6313
|
this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
|
|
5383
6314
|
const member = data;
|
|
5384
|
-
this
|
|
6315
|
+
this.#upsertMember(member.guild_id, member);
|
|
5385
6316
|
this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
|
|
5386
6317
|
});
|
|
5387
6318
|
this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
|
|
5388
6319
|
const member = data;
|
|
5389
|
-
this
|
|
6320
|
+
this.#upsertMember(member.guild_id, member);
|
|
5390
6321
|
this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
|
|
5391
6322
|
});
|
|
5392
|
-
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) =>
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
this.#gateway.on("
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
6323
|
+
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
|
|
6324
|
+
const member = data;
|
|
6325
|
+
this.guilds.members(member.guild_id).delete(member.user.id);
|
|
6326
|
+
this.emit("guildMemberRemove" /* GuildMemberRemove */, member);
|
|
6327
|
+
});
|
|
6328
|
+
this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => {
|
|
6329
|
+
const chunk = data;
|
|
6330
|
+
for (const member of chunk.members)
|
|
6331
|
+
this.#upsertMember(chunk.guild_id, member);
|
|
6332
|
+
this.emit("guildMembersChunk" /* GuildMembersChunk */, chunk);
|
|
6333
|
+
});
|
|
6334
|
+
this.#gateway.on("GUILD_BAN_ADD", (data) => {
|
|
6335
|
+
const ban = data;
|
|
6336
|
+
const bans = this.guilds.bans(ban.guild_id);
|
|
6337
|
+
bans.set(ban.user.id, {
|
|
6338
|
+
reason: bans.get(ban.user.id)?.reason ?? null,
|
|
6339
|
+
user: ban.user
|
|
6340
|
+
});
|
|
6341
|
+
this.guilds.members(ban.guild_id).delete(ban.user.id);
|
|
6342
|
+
this.emit("guildBanAdd" /* GuildBanAdd */, ban);
|
|
6343
|
+
});
|
|
6344
|
+
this.#gateway.on("GUILD_BAN_REMOVE", (data) => {
|
|
6345
|
+
const ban = data;
|
|
6346
|
+
this.guilds.bans(ban.guild_id).delete(ban.user.id);
|
|
6347
|
+
this.emit("guildBanRemove" /* GuildBanRemove */, ban);
|
|
6348
|
+
});
|
|
6349
|
+
this.#gateway.on("GUILD_ROLE_CREATE", (data) => {
|
|
6350
|
+
const event = data;
|
|
6351
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
6352
|
+
this.emit("guildRoleCreate" /* GuildRoleCreate */, event);
|
|
6353
|
+
});
|
|
6354
|
+
this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
|
|
6355
|
+
const event = data;
|
|
6356
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
6357
|
+
this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
|
|
6358
|
+
});
|
|
6359
|
+
this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
|
|
6360
|
+
const event = data;
|
|
6361
|
+
this.guilds.roles(event.guild_id).delete(event.role_id);
|
|
6362
|
+
this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
|
|
6363
|
+
});
|
|
6364
|
+
this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
|
|
6365
|
+
const event = data;
|
|
6366
|
+
if (this.#cache.emojis) {
|
|
6367
|
+
const emojis = this.guilds.emojis(event.guild_id);
|
|
6368
|
+
const current = new Set(event.emojis.map((emoji) => emoji.id));
|
|
6369
|
+
for (const id of [...emojis.cache.keys()])
|
|
6370
|
+
if (!current.has(id))
|
|
6371
|
+
emojis.delete(id);
|
|
6372
|
+
for (const emoji of event.emojis)
|
|
6373
|
+
emojis.upsert(emoji);
|
|
6374
|
+
}
|
|
6375
|
+
this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
|
|
6376
|
+
});
|
|
6377
|
+
this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
|
|
6378
|
+
const event = data;
|
|
6379
|
+
this.guilds.stickers(event.guild_id).sync(event.stickers);
|
|
6380
|
+
this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
|
|
6381
|
+
});
|
|
6382
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
|
|
6383
|
+
const sound = data;
|
|
6384
|
+
if (sound.guild_id)
|
|
6385
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
6386
|
+
this.emit("soundboardSoundCreate" /* SoundboardSoundCreate */, sound);
|
|
6387
|
+
});
|
|
6388
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_UPDATE", (data) => {
|
|
6389
|
+
const sound = data;
|
|
6390
|
+
if (sound.guild_id)
|
|
6391
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
6392
|
+
this.emit("soundboardSoundUpdate" /* SoundboardSoundUpdate */, sound);
|
|
6393
|
+
});
|
|
6394
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_DELETE", (data) => {
|
|
6395
|
+
const event = data;
|
|
6396
|
+
this.guilds.soundboard(event.guild_id).delete(event.sound_id);
|
|
6397
|
+
this.emit("soundboardSoundDelete" /* SoundboardSoundDelete */, event);
|
|
6398
|
+
});
|
|
6399
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUNDS_UPDATE", (data) => {
|
|
6400
|
+
const event = data;
|
|
6401
|
+
const sounds = this.guilds.soundboard(event.guild_id);
|
|
6402
|
+
sounds.clear();
|
|
6403
|
+
for (const sound of event.soundboard_sounds)
|
|
6404
|
+
sounds.set(sound.sound_id, sound);
|
|
6405
|
+
this.emit("soundboardSoundsUpdate" /* SoundboardSoundsUpdate */, event);
|
|
6406
|
+
});
|
|
6407
|
+
this.#gateway.on("ENTITLEMENT_CREATE", (data) => {
|
|
6408
|
+
const entitlement = data;
|
|
6409
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
6410
|
+
this.emit("entitlementCreate" /* EntitlementCreate */, entitlement);
|
|
6411
|
+
});
|
|
6412
|
+
this.#gateway.on("ENTITLEMENT_UPDATE", (data) => {
|
|
6413
|
+
const entitlement = data;
|
|
6414
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
6415
|
+
this.emit("entitlementUpdate" /* EntitlementUpdate */, entitlement);
|
|
6416
|
+
});
|
|
6417
|
+
this.#gateway.on("ENTITLEMENT_DELETE", (data) => {
|
|
6418
|
+
const entitlement = data;
|
|
6419
|
+
this.monetization?.delete(entitlement.id);
|
|
6420
|
+
this.emit("entitlementDelete" /* EntitlementDelete */, entitlement);
|
|
6421
|
+
});
|
|
5401
6422
|
this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
|
|
5402
|
-
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) =>
|
|
5403
|
-
|
|
5404
|
-
|
|
6423
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => {
|
|
6424
|
+
const event = data;
|
|
6425
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
6426
|
+
this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, event);
|
|
6427
|
+
});
|
|
6428
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => {
|
|
6429
|
+
const event = data;
|
|
6430
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
6431
|
+
this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, event);
|
|
6432
|
+
});
|
|
6433
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => {
|
|
6434
|
+
const event = data;
|
|
6435
|
+
this.guilds.scheduledEvents(event.guild_id).delete(event.id);
|
|
6436
|
+
this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, event);
|
|
6437
|
+
});
|
|
5405
6438
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
|
|
5406
6439
|
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
|
-
|
|
6440
|
+
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => {
|
|
6441
|
+
const rule = data;
|
|
6442
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
6443
|
+
this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, rule);
|
|
6444
|
+
});
|
|
6445
|
+
this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => {
|
|
6446
|
+
const rule = data;
|
|
6447
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
6448
|
+
this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, rule);
|
|
6449
|
+
});
|
|
6450
|
+
this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => {
|
|
6451
|
+
const rule = data;
|
|
6452
|
+
this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);
|
|
6453
|
+
this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
|
|
6454
|
+
});
|
|
5410
6455
|
this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
|
|
5411
6456
|
this.#gateway.on("CHANNEL_CREATE", (data) => {
|
|
5412
|
-
const channel =
|
|
5413
|
-
this.channels.update(channel);
|
|
6457
|
+
const channel = this.channels.upsert(data);
|
|
5414
6458
|
this.emit("channelCreate" /* ChannelCreate */, channel);
|
|
5415
6459
|
});
|
|
5416
6460
|
this.#gateway.on("CHANNEL_UPDATE", (data) => {
|
|
5417
|
-
const channel =
|
|
5418
|
-
this.channels.update(channel);
|
|
6461
|
+
const channel = this.channels.upsert(data);
|
|
5419
6462
|
this.emit("channelUpdate" /* ChannelUpdate */, channel);
|
|
5420
6463
|
});
|
|
5421
6464
|
this.#gateway.on("CHANNEL_DELETE", (data) => {
|
|
@@ -5425,13 +6468,11 @@ class Client extends EventEmitter2 {
|
|
|
5425
6468
|
});
|
|
5426
6469
|
this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
|
|
5427
6470
|
this.#gateway.on("THREAD_CREATE", (data) => {
|
|
5428
|
-
const channel =
|
|
5429
|
-
this.channels.update(channel);
|
|
6471
|
+
const channel = this.channels.upsert(data);
|
|
5430
6472
|
this.emit("threadCreate" /* ThreadCreate */, channel);
|
|
5431
6473
|
});
|
|
5432
6474
|
this.#gateway.on("THREAD_UPDATE", (data) => {
|
|
5433
|
-
const channel =
|
|
5434
|
-
this.channels.update(channel);
|
|
6475
|
+
const channel = this.channels.upsert(data);
|
|
5435
6476
|
this.emit("threadUpdate" /* ThreadUpdate */, channel);
|
|
5436
6477
|
});
|
|
5437
6478
|
this.#gateway.on("THREAD_DELETE", (data) => {
|
|
@@ -5439,16 +6480,48 @@ class Client extends EventEmitter2 {
|
|
|
5439
6480
|
this.channels.delete(payload.id);
|
|
5440
6481
|
this.emit("threadDelete" /* ThreadDelete */, payload);
|
|
5441
6482
|
});
|
|
5442
|
-
this.#gateway.on("THREAD_LIST_SYNC", (data) =>
|
|
6483
|
+
this.#gateway.on("THREAD_LIST_SYNC", (data) => {
|
|
6484
|
+
const sync = data;
|
|
6485
|
+
for (const thread of sync.threads)
|
|
6486
|
+
this.channels.upsert({ ...thread, guild_id: sync.guild_id });
|
|
6487
|
+
this.emit("threadListSync" /* ThreadListSync */, sync);
|
|
6488
|
+
});
|
|
5443
6489
|
this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
|
|
5444
6490
|
this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
|
|
5445
|
-
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) =>
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
6491
|
+
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => {
|
|
6492
|
+
const stage = data;
|
|
6493
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
6494
|
+
this.emit("stageInstanceCreate" /* StageInstanceCreate */, stage);
|
|
6495
|
+
});
|
|
6496
|
+
this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => {
|
|
6497
|
+
const stage = data;
|
|
6498
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
6499
|
+
this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, stage);
|
|
6500
|
+
});
|
|
6501
|
+
this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => {
|
|
6502
|
+
const stage = data;
|
|
6503
|
+
this.stageInstances.delete(stage.channel_id);
|
|
6504
|
+
this.emit("stageInstanceDelete" /* StageInstanceDelete */, stage);
|
|
6505
|
+
});
|
|
6506
|
+
this.#gateway.on("INVITE_CREATE", (data) => {
|
|
6507
|
+
const invite = data;
|
|
6508
|
+
if (invite.guild_id)
|
|
6509
|
+
this.guilds.invites(invite.guild_id).set(invite.code, invite);
|
|
6510
|
+
this.emit("inviteCreate" /* InviteCreate */, invite);
|
|
6511
|
+
});
|
|
6512
|
+
this.#gateway.on("INVITE_DELETE", (data) => {
|
|
6513
|
+
const invite = data;
|
|
6514
|
+
if (invite.guild_id)
|
|
6515
|
+
this.guilds.invites(invite.guild_id).delete(invite.code);
|
|
6516
|
+
this.emit("inviteDelete" /* InviteDelete */, invite);
|
|
6517
|
+
});
|
|
5450
6518
|
this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
|
|
5451
|
-
this.#gateway.on("VOICE_STATE_UPDATE", (data) =>
|
|
6519
|
+
this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
|
|
6520
|
+
const state = data;
|
|
6521
|
+
if (state.guild_id)
|
|
6522
|
+
this.#storeVoiceState(state.guild_id, state);
|
|
6523
|
+
this.emit("voiceStateUpdate" /* VoiceStateUpdate */, state);
|
|
6524
|
+
});
|
|
5452
6525
|
this.#gateway.on("VOICE_SERVER_UPDATE", (data) => this.emit("voiceServerUpdate" /* VoiceServerUpdate */, data));
|
|
5453
6526
|
this.#gateway.on("PRESENCE_UPDATE", (data) => this.emit("presenceUpdate" /* PresenceUpdate */, data));
|
|
5454
6527
|
this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
|
|
@@ -5456,6 +6529,80 @@ class Client extends EventEmitter2 {
|
|
|
5456
6529
|
this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
|
|
5457
6530
|
this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
|
|
5458
6531
|
}
|
|
6532
|
+
#observeMessage(message) {
|
|
6533
|
+
if (!this.channels.has(message.channelId))
|
|
6534
|
+
this.channels.set(message.channelId, message.channel);
|
|
6535
|
+
if (this.#cache.users)
|
|
6536
|
+
this.#merge(this.users, message.author.id, message.author);
|
|
6537
|
+
}
|
|
6538
|
+
#upsertMember(guildId, data) {
|
|
6539
|
+
const member = new GuildMember({ ...data, guild_id: guildId });
|
|
6540
|
+
if (this.#cache.users)
|
|
6541
|
+
this.#merge(this.users, member.user.id, member.user);
|
|
6542
|
+
if (!this.#cache.members)
|
|
6543
|
+
return member;
|
|
6544
|
+
return this.#merge(this.guilds.members(guildId), member.user.id, member);
|
|
6545
|
+
}
|
|
6546
|
+
#storeVoiceState(guildId, state) {
|
|
6547
|
+
const states = this.guilds.voiceStates(guildId);
|
|
6548
|
+
if (state.channel_id)
|
|
6549
|
+
states.set(state.user_id, state);
|
|
6550
|
+
else
|
|
6551
|
+
states.delete(state.user_id);
|
|
6552
|
+
}
|
|
6553
|
+
#upsertRole(guildId, data) {
|
|
6554
|
+
if (!this.#cache.roles)
|
|
6555
|
+
return new Role(data);
|
|
6556
|
+
return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
|
|
6557
|
+
}
|
|
6558
|
+
#merge(manager, id, next) {
|
|
6559
|
+
const existing = manager.get(id);
|
|
6560
|
+
if (!existing) {
|
|
6561
|
+
manager.set(id, next);
|
|
6562
|
+
return next;
|
|
6563
|
+
}
|
|
6564
|
+
for (const [key, value] of Object.entries(next))
|
|
6565
|
+
if (value !== undefined)
|
|
6566
|
+
existing[key] = value;
|
|
6567
|
+
return existing;
|
|
6568
|
+
}
|
|
6569
|
+
createCollector(event, options = {}) {
|
|
6570
|
+
const collector = new Collector(options);
|
|
6571
|
+
let order = 0;
|
|
6572
|
+
const listener = (...args) => {
|
|
6573
|
+
const item = args[0];
|
|
6574
|
+
const id = item?.id;
|
|
6575
|
+
const key = options.key?.(item) ?? (typeof id === "string" ? id : String(order++));
|
|
6576
|
+
collector.handle(key, item).catch((error) => this.emit("error" /* Error */, error instanceof Error ? error : new Error(String(error))));
|
|
6577
|
+
};
|
|
6578
|
+
this.on(event, listener);
|
|
6579
|
+
collector.onDispose(() => this.off(event, listener));
|
|
6580
|
+
return collector;
|
|
6581
|
+
}
|
|
6582
|
+
permissionsFor(memberId, guildOrChannelId) {
|
|
6583
|
+
let channel = this.channels.get(guildOrChannelId);
|
|
6584
|
+
if (channel?.isThread()) {
|
|
6585
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
6586
|
+
if (!channel)
|
|
6587
|
+
return null;
|
|
6588
|
+
}
|
|
6589
|
+
const guildId = channel?.guildId ?? guildOrChannelId;
|
|
6590
|
+
const guild = this.guilds.get(guildId);
|
|
6591
|
+
const member = this.guilds.members(guildId).get(memberId);
|
|
6592
|
+
if (!guild || !member)
|
|
6593
|
+
return null;
|
|
6594
|
+
return computePermissions({
|
|
6595
|
+
guildId,
|
|
6596
|
+
ownerId: guild.ownerId,
|
|
6597
|
+
memberId,
|
|
6598
|
+
memberRoleIds: member.roleIds,
|
|
6599
|
+
roles: this.guilds.roles(guildId).values(),
|
|
6600
|
+
overwrites: channel?.permissionOverwrites
|
|
6601
|
+
});
|
|
6602
|
+
}
|
|
6603
|
+
fetchDefaultSoundboardSounds() {
|
|
6604
|
+
return this.rest.get(Routes.soundboardDefaultSounds());
|
|
6605
|
+
}
|
|
5459
6606
|
async login(token) {
|
|
5460
6607
|
if (this.state === "destroyed")
|
|
5461
6608
|
throw new Error("Cannot login a destroyed client.");
|
|
@@ -5492,6 +6639,14 @@ class Client extends EventEmitter2 {
|
|
|
5492
6639
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
5493
6640
|
return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);
|
|
5494
6641
|
}
|
|
6642
|
+
interactionWebhookMessage(method, applicationId, token, messageId, data) {
|
|
6643
|
+
const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
|
|
6644
|
+
if (method === "GET")
|
|
6645
|
+
return this.rest.get(path);
|
|
6646
|
+
if (method === "PATCH")
|
|
6647
|
+
return this.rest.patch(path, data);
|
|
6648
|
+
return this.rest.delete(path);
|
|
6649
|
+
}
|
|
5495
6650
|
fetchWebhook(id, token) {
|
|
5496
6651
|
return this.rest.get(token ? `/webhooks/${id}/${token}` : `/webhooks/${id}`);
|
|
5497
6652
|
}
|
|
@@ -5647,6 +6802,21 @@ class HandlerRegistry {
|
|
|
5647
6802
|
return this.dispatch(event, ...args);
|
|
5648
6803
|
}
|
|
5649
6804
|
}
|
|
6805
|
+
// packages/sharding/package.json
|
|
6806
|
+
var package_default2 = {
|
|
6807
|
+
name: "@lunibee/sharding",
|
|
6808
|
+
version: "0.2.0",
|
|
6809
|
+
type: "module",
|
|
6810
|
+
module: "./src/index.ts",
|
|
6811
|
+
types: "./src/index.ts",
|
|
6812
|
+
exports: {
|
|
6813
|
+
".": "./src/index.ts"
|
|
6814
|
+
},
|
|
6815
|
+
dependencies: {
|
|
6816
|
+
"@lunibee/ws": "workspace:*"
|
|
6817
|
+
}
|
|
6818
|
+
};
|
|
6819
|
+
|
|
5650
6820
|
// packages/sharding/src/bus.ts
|
|
5651
6821
|
var REPLY_TYPE = "__lunibee:reply";
|
|
5652
6822
|
|
|
@@ -5824,7 +6994,7 @@ class ClusterManager {
|
|
|
5824
6994
|
const response = await fetch("https://discord.com/api/v10/gateway/bot", {
|
|
5825
6995
|
headers: {
|
|
5826
6996
|
Authorization: `Bot ${this.#options.token}`,
|
|
5827
|
-
"User-Agent":
|
|
6997
|
+
"User-Agent": `Lunibee/${package_default2.version}`
|
|
5828
6998
|
}
|
|
5829
6999
|
});
|
|
5830
7000
|
if (!response.ok) {
|
|
@@ -5975,6 +7145,34 @@ class ClusterManager {
|
|
|
5975
7145
|
|
|
5976
7146
|
// packages/sharding/src/index.ts
|
|
5977
7147
|
var sleep3 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7148
|
+
function needsConnection(gateway) {
|
|
7149
|
+
return gateway.state === "CONNECT" /* Connect */ || gateway.state === "RECONNECT" /* Reconnect */ || gateway.state === "CLOSED" /* Closed */;
|
|
7150
|
+
}
|
|
7151
|
+
var HANDSHAKE_SENT = new Set([
|
|
7152
|
+
"IDENTIFY" /* Identify */,
|
|
7153
|
+
"RESUME" /* Resume */,
|
|
7154
|
+
"READY" /* Ready */,
|
|
7155
|
+
"DISPATCH" /* Dispatch */,
|
|
7156
|
+
"HEARTBEAT" /* Heartbeat */,
|
|
7157
|
+
"CLOSED" /* Closed */
|
|
7158
|
+
]);
|
|
7159
|
+
function handshakeSent(gateway, timeout) {
|
|
7160
|
+
if (HANDSHAKE_SENT.has(gateway.state))
|
|
7161
|
+
return Promise.resolve();
|
|
7162
|
+
return new Promise((resolve) => {
|
|
7163
|
+
const done = () => {
|
|
7164
|
+
clearTimeout(timer);
|
|
7165
|
+
gateway.off("stateChange", onState);
|
|
7166
|
+
resolve();
|
|
7167
|
+
};
|
|
7168
|
+
const onState = (change) => {
|
|
7169
|
+
if (HANDSHAKE_SENT.has(change.next))
|
|
7170
|
+
done();
|
|
7171
|
+
};
|
|
7172
|
+
const timer = setTimeout(done, timeout);
|
|
7173
|
+
gateway.on("stateChange", onState);
|
|
7174
|
+
});
|
|
7175
|
+
}
|
|
5978
7176
|
|
|
5979
7177
|
class ShardManager {
|
|
5980
7178
|
static IDENTIFY_INTERVAL = 5000;
|
|
@@ -5987,6 +7185,7 @@ class ShardManager {
|
|
|
5987
7185
|
#destroyed = false;
|
|
5988
7186
|
#auto;
|
|
5989
7187
|
#autoScaleTimer;
|
|
7188
|
+
#gatewayInfo;
|
|
5990
7189
|
constructor(options) {
|
|
5991
7190
|
if (!options.token?.trim())
|
|
5992
7191
|
throw new TypeError("A Discord bot token is required.");
|
|
@@ -5999,6 +7198,10 @@ class ShardManager {
|
|
|
5999
7198
|
throw new RangeError("autoScaleInterval must be an integer of at least 1000 milliseconds.");
|
|
6000
7199
|
if (options.spawnDelay !== undefined && (!Number.isFinite(options.spawnDelay) || options.spawnDelay < 0))
|
|
6001
7200
|
throw new RangeError("spawnDelay must be a non-negative finite number of milliseconds.");
|
|
7201
|
+
if (options.maxConcurrency !== undefined && (!Number.isInteger(options.maxConcurrency) || options.maxConcurrency < 1))
|
|
7202
|
+
throw new RangeError("maxConcurrency must be a positive integer.");
|
|
7203
|
+
if (options.handshakeTimeout !== undefined && (!Number.isFinite(options.handshakeTimeout) || options.handshakeTimeout < 0))
|
|
7204
|
+
throw new RangeError("handshakeTimeout must be a non-negative number of milliseconds.");
|
|
6002
7205
|
this.#auto = options.shardCount === "auto";
|
|
6003
7206
|
this.#options = {
|
|
6004
7207
|
spawnDelay: ShardManager.IDENTIFY_INTERVAL,
|
|
@@ -6008,10 +7211,13 @@ class ShardManager {
|
|
|
6008
7211
|
this.#initialize(count);
|
|
6009
7212
|
}
|
|
6010
7213
|
async fetchRecommendedShardCount() {
|
|
7214
|
+
return (await this.fetchGatewayInfo()).shards;
|
|
7215
|
+
}
|
|
7216
|
+
async fetchGatewayInfo() {
|
|
6011
7217
|
const response = await fetch("https://discord.com/api/v10/gateway/bot", {
|
|
6012
7218
|
headers: {
|
|
6013
7219
|
Authorization: `Bot ${this.#options.token}`,
|
|
6014
|
-
"User-Agent":
|
|
7220
|
+
"User-Agent": `Lunibee/${package_default2.version}`
|
|
6015
7221
|
}
|
|
6016
7222
|
});
|
|
6017
7223
|
if (!response.ok)
|
|
@@ -6019,7 +7225,17 @@ class ShardManager {
|
|
|
6019
7225
|
const data = await response.json();
|
|
6020
7226
|
if (typeof data.shards !== "number" || !Number.isInteger(data.shards) || data.shards < 1)
|
|
6021
7227
|
throw new Error("Gateway discovery returned an invalid shard count.");
|
|
6022
|
-
|
|
7228
|
+
const limit = data.session_start_limit;
|
|
7229
|
+
const info = { shards: data.shards };
|
|
7230
|
+
if (limit && typeof limit.total === "number" && typeof limit.remaining === "number" && typeof limit.reset_after === "number" && typeof limit.max_concurrency === "number")
|
|
7231
|
+
info.sessionStartLimit = {
|
|
7232
|
+
total: limit.total,
|
|
7233
|
+
remaining: limit.remaining,
|
|
7234
|
+
resetAfter: limit.reset_after,
|
|
7235
|
+
maxConcurrency: Math.max(1, limit.max_concurrency)
|
|
7236
|
+
};
|
|
7237
|
+
this.#gatewayInfo = info;
|
|
7238
|
+
return info;
|
|
6023
7239
|
}
|
|
6024
7240
|
async connect() {
|
|
6025
7241
|
if (this.#autoScaleTimer) {
|
|
@@ -6027,17 +7243,25 @@ class ShardManager {
|
|
|
6027
7243
|
this.#autoScaleTimer = undefined;
|
|
6028
7244
|
}
|
|
6029
7245
|
await this.#ensureInitialized();
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
}
|
|
7246
|
+
const limit = this.#gatewayInfo?.sessionStartLimit;
|
|
7247
|
+
const ids = [...this.shards].filter(([, gateway]) => needsConnection(gateway)).map(([id]) => id);
|
|
7248
|
+
if (limit && limit.remaining < ids.length)
|
|
7249
|
+
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.`);
|
|
7250
|
+
const concurrency = Math.min(this.#options.maxConcurrency ?? limit?.maxConcurrency ?? 1, limit?.maxConcurrency ?? Infinity);
|
|
7251
|
+
for (let start = 0;start < ids.length; start += concurrency) {
|
|
7252
|
+
const round = ids.slice(start, start + concurrency);
|
|
7253
|
+
const results = await Promise.allSettled(round.map((id) => this.shards.get(id).connect()));
|
|
7254
|
+
const failed = results.findIndex((result) => result.status === "rejected");
|
|
7255
|
+
if (failed !== -1) {
|
|
6034
7256
|
this.destroy();
|
|
6035
|
-
throw new Error(`Failed to connect shard ${
|
|
6036
|
-
cause:
|
|
7257
|
+
throw new Error(`Failed to connect shard ${round[failed]}.`, {
|
|
7258
|
+
cause: results[failed].reason
|
|
6037
7259
|
});
|
|
6038
7260
|
}
|
|
6039
|
-
if (
|
|
7261
|
+
if (start + concurrency < ids.length && this.#options.spawnDelay && this.#options.spawnDelay > 0) {
|
|
7262
|
+
await Promise.all(round.map((id) => handshakeSent(this.shards.get(id), this.#options.handshakeTimeout ?? 15000)));
|
|
6040
7263
|
await sleep3(this.#options.spawnDelay);
|
|
7264
|
+
}
|
|
6041
7265
|
}
|
|
6042
7266
|
if (this.#options.autoScaleInterval && !this.#autoScaleTimer) {
|
|
6043
7267
|
this.#autoScaleTimer = setInterval(() => {
|
|
@@ -6080,6 +7304,13 @@ class ShardManager {
|
|
|
6080
7304
|
get(id) {
|
|
6081
7305
|
return this.shards.get(id);
|
|
6082
7306
|
}
|
|
7307
|
+
health() {
|
|
7308
|
+
return [...this.shards].map(([id, gateway]) => ({
|
|
7309
|
+
id,
|
|
7310
|
+
state: gateway.state,
|
|
7311
|
+
ping: gateway.ping
|
|
7312
|
+
}));
|
|
7313
|
+
}
|
|
6083
7314
|
values() {
|
|
6084
7315
|
return [...this.shards].map(([id, gateway]) => ({ id, gateway }));
|
|
6085
7316
|
}
|
|
@@ -6203,12 +7434,14 @@ class VoiceConnection {
|
|
|
6203
7434
|
if (this.state === "destroyed" /* Destroyed */)
|
|
6204
7435
|
return;
|
|
6205
7436
|
this.#closeTransports();
|
|
7437
|
+
this.receiver.close();
|
|
6206
7438
|
this.#transition("disconnected" /* Disconnected */);
|
|
6207
7439
|
}
|
|
6208
7440
|
destroy() {
|
|
6209
7441
|
if (this.state === "destroyed" /* Destroyed */)
|
|
6210
7442
|
return;
|
|
6211
7443
|
this.#closeTransports();
|
|
7444
|
+
this.receiver.close();
|
|
6212
7445
|
this.channelId = undefined;
|
|
6213
7446
|
this.#transition("destroyed" /* Destroyed */);
|
|
6214
7447
|
this.#listeners.clear();
|
|
@@ -6416,6 +7649,8 @@ class VoiceReceiver {
|
|
|
6416
7649
|
this.#ssrcMap.set(ssrc, userId);
|
|
6417
7650
|
}
|
|
6418
7651
|
subscribe(userId) {
|
|
7652
|
+
if (this.connection.state === "destroyed" /* Destroyed */)
|
|
7653
|
+
throw new VoiceError("Voice connection has been destroyed.");
|
|
6419
7654
|
let controllerRef;
|
|
6420
7655
|
const stream = new ReadableStream({
|
|
6421
7656
|
start: (controller) => {
|
|
@@ -6436,6 +7671,16 @@ class VoiceReceiver {
|
|
|
6436
7671
|
});
|
|
6437
7672
|
return new AudioStream(stream, { title: `User ${userId} Audio` });
|
|
6438
7673
|
}
|
|
7674
|
+
close() {
|
|
7675
|
+
for (const controllers of this.#streams.values())
|
|
7676
|
+
for (const controller of controllers) {
|
|
7677
|
+
try {
|
|
7678
|
+
controller.close();
|
|
7679
|
+
} catch {}
|
|
7680
|
+
}
|
|
7681
|
+
this.#streams.clear();
|
|
7682
|
+
this.#ssrcMap.clear();
|
|
7683
|
+
}
|
|
6439
7684
|
onPacket(packet) {
|
|
6440
7685
|
if (packet.length < 12)
|
|
6441
7686
|
return;
|
|
@@ -6663,10 +7908,13 @@ class ActionRowBuilder {
|
|
|
6663
7908
|
return this;
|
|
6664
7909
|
}
|
|
6665
7910
|
toJSON() {
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
7911
|
+
const components = this.#components.map((component) => component.toJSON());
|
|
7912
|
+
if (components.length === 0)
|
|
7913
|
+
throw new RangeError("An action row needs at least one component.");
|
|
7914
|
+
const types = components.map((component) => component.type);
|
|
7915
|
+
if (types.some((type) => type !== ComponentType.Button) && components.length > 1)
|
|
7916
|
+
throw new RangeError("A select menu or text input must be alone in its action row.");
|
|
7917
|
+
return { type: ComponentType.ActionRow, components };
|
|
6670
7918
|
}
|
|
6671
7919
|
}
|
|
6672
7920
|
|
|
@@ -6721,6 +7969,12 @@ class StringSelectBuilder {
|
|
|
6721
7969
|
return this;
|
|
6722
7970
|
}
|
|
6723
7971
|
toJSON() {
|
|
7972
|
+
assertSelect(this.#data);
|
|
7973
|
+
const count = this.#data.options?.length ?? 0;
|
|
7974
|
+
if (count === 0)
|
|
7975
|
+
throw new RangeError("A string select needs at least one option.");
|
|
7976
|
+
if ((this.#data.max_values ?? 1) > count)
|
|
7977
|
+
throw new RangeError("max_values cannot exceed the number of options.");
|
|
6724
7978
|
return structuredClone(this.#data);
|
|
6725
7979
|
}
|
|
6726
7980
|
}
|
|
@@ -6731,9 +7985,20 @@ class ButtonBuilder {
|
|
|
6731
7985
|
style: ButtonStyle.Secondary
|
|
6732
7986
|
};
|
|
6733
7987
|
setStyle(style) {
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
7988
|
+
const data = this.#data;
|
|
7989
|
+
data.style = style;
|
|
7990
|
+
if (style === ButtonStyle.Link) {
|
|
7991
|
+
delete data.custom_id;
|
|
7992
|
+
delete data.sku_id;
|
|
7993
|
+
} else if (style === ButtonStyle.Premium) {
|
|
7994
|
+
delete data.custom_id;
|
|
7995
|
+
delete data.url;
|
|
7996
|
+
delete data.label;
|
|
7997
|
+
delete data.emoji;
|
|
7998
|
+
} else {
|
|
7999
|
+
delete data.url;
|
|
8000
|
+
delete data.sku_id;
|
|
8001
|
+
}
|
|
6737
8002
|
return this;
|
|
6738
8003
|
}
|
|
6739
8004
|
setCustomId(value) {
|
|
@@ -6758,11 +8023,16 @@ class ButtonBuilder {
|
|
|
6758
8023
|
cause: error
|
|
6759
8024
|
});
|
|
6760
8025
|
}
|
|
6761
|
-
this
|
|
6762
|
-
delete this.#data.custom_id;
|
|
8026
|
+
this.setStyle(ButtonStyle.Link);
|
|
6763
8027
|
this.#data.url = url.toString();
|
|
6764
8028
|
return this;
|
|
6765
8029
|
}
|
|
8030
|
+
setSKUId(skuId) {
|
|
8031
|
+
validateText(skuId, 20, "Button SKU ID");
|
|
8032
|
+
this.setStyle(ButtonStyle.Premium);
|
|
8033
|
+
this.#data.sku_id = skuId;
|
|
8034
|
+
return this;
|
|
8035
|
+
}
|
|
6766
8036
|
setEmoji(emoji) {
|
|
6767
8037
|
this.#data.emoji = typeof emoji === "string" ? { name: emoji } : { ...emoji };
|
|
6768
8038
|
return this;
|
|
@@ -6772,7 +8042,26 @@ class ButtonBuilder {
|
|
|
6772
8042
|
return this;
|
|
6773
8043
|
}
|
|
6774
8044
|
toJSON() {
|
|
6775
|
-
|
|
8045
|
+
const data = this.#data;
|
|
8046
|
+
if (data.style === ButtonStyle.Link) {
|
|
8047
|
+
if (!data.url)
|
|
8048
|
+
throw new TypeError("Link buttons require a URL.");
|
|
8049
|
+
if (data.custom_id || data.sku_id)
|
|
8050
|
+
throw new TypeError("Link buttons cannot have a custom ID or SKU ID.");
|
|
8051
|
+
} else if (data.style === ButtonStyle.Premium) {
|
|
8052
|
+
if (!data.sku_id)
|
|
8053
|
+
throw new TypeError("Premium buttons require a SKU ID.");
|
|
8054
|
+
if (data.custom_id || data.url || data.label || data.emoji)
|
|
8055
|
+
throw new TypeError("Premium buttons cannot have a custom ID, URL, label or emoji.");
|
|
8056
|
+
} else {
|
|
8057
|
+
if (!data.custom_id)
|
|
8058
|
+
throw new TypeError("Non-link buttons require a custom ID.");
|
|
8059
|
+
if (data.url || data.sku_id)
|
|
8060
|
+
throw new TypeError("Only link buttons have a URL and only premium buttons have a SKU ID.");
|
|
8061
|
+
}
|
|
8062
|
+
if (data.style !== ButtonStyle.Premium && !data.label && !data.emoji)
|
|
8063
|
+
throw new TypeError("Buttons require a label or an emoji.");
|
|
8064
|
+
return structuredClone(data);
|
|
6776
8065
|
}
|
|
6777
8066
|
}
|
|
6778
8067
|
|
|
@@ -6816,6 +8105,7 @@ class EntitySelectBuilder {
|
|
|
6816
8105
|
return this;
|
|
6817
8106
|
}
|
|
6818
8107
|
toJSON() {
|
|
8108
|
+
assertSelect(this.#data);
|
|
6819
8109
|
return structuredClone(this.#data);
|
|
6820
8110
|
}
|
|
6821
8111
|
}
|
|
@@ -6843,6 +8133,10 @@ class ModalBuilder {
|
|
|
6843
8133
|
return this;
|
|
6844
8134
|
}
|
|
6845
8135
|
toJSON() {
|
|
8136
|
+
if (!this.#custom_id || !this.#title)
|
|
8137
|
+
throw new TypeError("Modals require a custom ID and a title.");
|
|
8138
|
+
if (this.#components.length === 0)
|
|
8139
|
+
throw new RangeError("Modals require at least one component.");
|
|
6846
8140
|
return {
|
|
6847
8141
|
type: 9,
|
|
6848
8142
|
...this.#custom_id ? { custom_id: this.#custom_id } : {},
|
|
@@ -6896,7 +8190,12 @@ class TextInputBuilder {
|
|
|
6896
8190
|
return this;
|
|
6897
8191
|
}
|
|
6898
8192
|
toJSON() {
|
|
6899
|
-
|
|
8193
|
+
const data = this.#data;
|
|
8194
|
+
if (!data.custom_id)
|
|
8195
|
+
throw new TypeError("Text inputs require a custom ID.");
|
|
8196
|
+
if (data.min_length !== undefined && data.max_length !== undefined && data.min_length > data.max_length)
|
|
8197
|
+
throw new RangeError("min_length cannot exceed max_length.");
|
|
8198
|
+
return structuredClone(data);
|
|
6900
8199
|
}
|
|
6901
8200
|
}
|
|
6902
8201
|
|
|
@@ -7123,6 +8422,12 @@ class ChannelSelectMenuBuilder extends EntitySelectBuilder {
|
|
|
7123
8422
|
super(ComponentType.ChannelSelect);
|
|
7124
8423
|
}
|
|
7125
8424
|
}
|
|
8425
|
+
function assertSelect(data) {
|
|
8426
|
+
if (!data.custom_id)
|
|
8427
|
+
throw new TypeError("Select menus require a custom ID.");
|
|
8428
|
+
if ((data.min_values ?? 1) > (data.max_values ?? 1))
|
|
8429
|
+
throw new RangeError("min_values cannot exceed max_values.");
|
|
8430
|
+
}
|
|
7126
8431
|
// packages/builders/src/commands.ts
|
|
7127
8432
|
var ApplicationCommandOptionType2 = {
|
|
7128
8433
|
Subcommand: 1,
|
|
@@ -7637,6 +8942,8 @@ export {
|
|
|
7637
8942
|
GuildMemberManager,
|
|
7638
8943
|
GuildOnboarding,
|
|
7639
8944
|
GuildScheduledEventManager,
|
|
8945
|
+
GuildSoundboardManager,
|
|
8946
|
+
GuildStickerManager,
|
|
7640
8947
|
GuildWelcomeScreen,
|
|
7641
8948
|
HandlerRegistry,
|
|
7642
8949
|
HttpTransport,
|
|
@@ -7662,6 +8969,7 @@ export {
|
|
|
7662
8969
|
MessageManager,
|
|
7663
8970
|
ModalBuilder,
|
|
7664
8971
|
ModalSubmitInteraction,
|
|
8972
|
+
MonetizationManager,
|
|
7665
8973
|
NewsChannel,
|
|
7666
8974
|
NumberOptionBuilder,
|
|
7667
8975
|
OnboardingPrompt,
|
|
@@ -7739,6 +9047,7 @@ export {
|
|
|
7739
9047
|
classifyFrame,
|
|
7740
9048
|
classifyPayload,
|
|
7741
9049
|
codeBlock,
|
|
9050
|
+
computePermissions,
|
|
7742
9051
|
createAudioPlayer,
|
|
7743
9052
|
createAudioResource,
|
|
7744
9053
|
createChannel,
|
|
@@ -7762,6 +9071,7 @@ export {
|
|
|
7762
9071
|
normalizeRoutePath,
|
|
7763
9072
|
orderedList,
|
|
7764
9073
|
randomInt,
|
|
9074
|
+
redactPath,
|
|
7765
9075
|
resolveGatewayIntents,
|
|
7766
9076
|
resumePayload,
|
|
7767
9077
|
roleMention,
|
|
@@ -7776,4 +9086,4 @@ export {
|
|
|
7776
9086
|
userMention
|
|
7777
9087
|
};
|
|
7778
9088
|
|
|
7779
|
-
//# debugId=
|
|
9089
|
+
//# debugId=726AE42ABABEBEA864756E2164756E21
|