lunibee 0.1.8 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/builders/components.d.ts +30 -2
- package/dist/builders/embed.d.ts +7 -7
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +110 -18
- package/dist/builders/index.js.map +6 -6
- package/dist/collection/index.d.ts +68 -1
- package/dist/collection/index.js +334 -1
- package/dist/collection/index.js.map +3 -3
- package/dist/core/collector.d.ts +13 -0
- package/dist/core/events.d.ts +29 -3
- package/dist/core/index.d.ts +25 -9
- package/dist/core/index.js +1745 -134
- package/dist/core/index.js.map +30 -26
- package/dist/core/permissions.d.ts +48 -0
- package/dist/index.js +2102 -362
- package/dist/index.js.map +36 -34
- package/dist/managers/advanced.d.ts +116 -0
- package/dist/managers/base.d.ts +13 -2
- package/dist/managers/emoji.d.ts +1 -1
- package/dist/managers/guild-resources.d.ts +22 -2
- package/dist/managers/guild.d.ts +31 -3
- package/dist/managers/index.d.ts +38 -6
- package/dist/managers/index.js +996 -160
- package/dist/managers/index.js.map +20 -18
- package/dist/managers/member.d.ts +13 -12
- package/dist/managers/message.d.ts +21 -4
- package/dist/rest/errors.d.ts +33 -0
- package/dist/rest/index.d.ts +1 -1
- package/dist/rest/index.js +52 -6
- package/dist/rest/index.js.map +5 -5
- package/dist/rest/routes.d.ts +20 -0
- package/dist/sharding/index.d.ts +29 -0
- package/dist/sharding/index.js +99 -15
- package/dist/sharding/index.js.map +8 -8
- package/dist/structures/base.d.ts +38 -0
- package/dist/structures/index.d.ts +29 -0
- package/dist/structures/index.js +208 -46
- package/dist/structures/index.js.map +13 -12
- package/dist/structures/interactions.d.ts +51 -1
- package/dist/structures/options.d.ts +2 -0
- package/dist/structures/resources.d.ts +29 -3
- package/dist/types/gateway.d.ts +16 -0
- package/dist/types/index.d.ts +67 -1
- package/dist/types/index.js.map +3 -3
- package/dist/utils/args.d.ts +79 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +190 -2
- package/dist/utils/index.js.map +5 -4
- package/dist/voice/index.d.ts +3 -0
- package/dist/voice/index.js +15 -1
- package/dist/voice/index.js.map +3 -3
- package/dist/ws/index.js +13 -5
- package/dist/ws/index.js.map +6 -6
- package/package.json +14 -14
package/dist/core/index.js
CHANGED
|
@@ -53,8 +53,11 @@ var Permission = {
|
|
|
53
53
|
createEvents: 1n << 44n,
|
|
54
54
|
useExternalSounds: 1n << 45n,
|
|
55
55
|
sendVoiceMessages: 1n << 46n,
|
|
56
|
+
setVoiceChannelStatus: 1n << 48n,
|
|
56
57
|
sendPolls: 1n << 49n,
|
|
57
|
-
useExternalApps: 1n << 50n
|
|
58
|
+
useExternalApps: 1n << 50n,
|
|
59
|
+
pinMessages: 1n << 51n,
|
|
60
|
+
bypassSlowmode: 1n << 52n
|
|
58
61
|
};
|
|
59
62
|
var Permissions = {
|
|
60
63
|
CreateInstantInvite: 1n << 0n,
|
|
@@ -104,8 +107,11 @@ var Permissions = {
|
|
|
104
107
|
CreateEvents: 1n << 44n,
|
|
105
108
|
UseExternalSounds: 1n << 45n,
|
|
106
109
|
SendVoiceMessages: 1n << 46n,
|
|
110
|
+
SetVoiceChannelStatus: 1n << 48n,
|
|
107
111
|
SendPolls: 1n << 49n,
|
|
108
|
-
UseExternalApps: 1n << 50n
|
|
112
|
+
UseExternalApps: 1n << 50n,
|
|
113
|
+
PinMessages: 1n << 51n,
|
|
114
|
+
BypassSlowmode: 1n << 52n
|
|
109
115
|
};
|
|
110
116
|
var PermissionFlagsBits = {
|
|
111
117
|
CreateInstantInvite: 1n << 0n,
|
|
@@ -155,8 +161,11 @@ var PermissionFlagsBits = {
|
|
|
155
161
|
CreateEvents: 1n << 44n,
|
|
156
162
|
UseExternalSounds: 1n << 45n,
|
|
157
163
|
SendVoiceMessages: 1n << 46n,
|
|
164
|
+
SetVoiceChannelStatus: 1n << 48n,
|
|
158
165
|
SendPolls: 1n << 49n,
|
|
159
|
-
UseExternalApps: 1n << 50n
|
|
166
|
+
UseExternalApps: 1n << 50n,
|
|
167
|
+
PinMessages: 1n << 51n,
|
|
168
|
+
BypassSlowmode: 1n << 52n
|
|
160
169
|
};
|
|
161
170
|
|
|
162
171
|
class PermissionSet {
|
|
@@ -358,6 +367,10 @@ class PermissionSet {
|
|
|
358
367
|
}
|
|
359
368
|
return false;
|
|
360
369
|
}
|
|
370
|
+
missing(...permissions) {
|
|
371
|
+
const wanted = new PermissionSet(permissions);
|
|
372
|
+
return wanted.toArray().filter((name) => !this.has(name));
|
|
373
|
+
}
|
|
361
374
|
add(...permissions) {
|
|
362
375
|
let bitfield = this.bitfield;
|
|
363
376
|
for (let i = 0;i < permissions.length; i++) {
|
|
@@ -383,6 +396,11 @@ class PermissionSet {
|
|
|
383
396
|
toArray() {
|
|
384
397
|
return Object.keys(Permission).filter((permission) => this.has(permission));
|
|
385
398
|
}
|
|
399
|
+
static #renamed = {
|
|
400
|
+
ManageEmojisAndStickers: "ManageGuildExpressions",
|
|
401
|
+
ManageEmojis: "ManageGuildExpressions",
|
|
402
|
+
UseSlashCommands: "UseApplicationCommands"
|
|
403
|
+
};
|
|
386
404
|
#resolve(permission) {
|
|
387
405
|
if (typeof permission === "bigint")
|
|
388
406
|
return permission;
|
|
@@ -397,6 +415,9 @@ class PermissionSet {
|
|
|
397
415
|
return bit;
|
|
398
416
|
}
|
|
399
417
|
if (typeof permission === "string") {
|
|
418
|
+
const renamed = PermissionSet.#renamed[permission];
|
|
419
|
+
if (renamed)
|
|
420
|
+
return this.#resolve(renamed);
|
|
400
421
|
if (permission in Permission)
|
|
401
422
|
return Permission[permission];
|
|
402
423
|
if (permission in Permissions)
|
|
@@ -419,6 +440,35 @@ class PermissionsBitField extends PermissionSet {
|
|
|
419
440
|
super(value);
|
|
420
441
|
}
|
|
421
442
|
}
|
|
443
|
+
var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
|
|
444
|
+
var bits = (value) => new PermissionSet(value).bitfield;
|
|
445
|
+
function computePermissions(context) {
|
|
446
|
+
if (context.ownerId !== undefined && context.ownerId === context.memberId)
|
|
447
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
448
|
+
const roles = new Map(context.roles.map((role) => [role.id, role]));
|
|
449
|
+
let base = bits(roles.get(context.guildId)?.permissions ?? 0n);
|
|
450
|
+
for (const id of context.memberRoleIds)
|
|
451
|
+
base |= bits(roles.get(id)?.permissions ?? 0n);
|
|
452
|
+
if (base & Permission.administrator)
|
|
453
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
454
|
+
const overwrites = context.overwrites ?? [];
|
|
455
|
+
const everyone = overwrites.find((o) => o.id === context.guildId);
|
|
456
|
+
if (everyone)
|
|
457
|
+
base = base & ~bits(everyone.deny) | bits(everyone.allow);
|
|
458
|
+
const memberRoles = new Set(context.memberRoleIds);
|
|
459
|
+
let allow = 0n;
|
|
460
|
+
let deny = 0n;
|
|
461
|
+
for (const overwrite of overwrites)
|
|
462
|
+
if (overwrite.type === 0 /* Role */ && overwrite.id !== context.guildId && memberRoles.has(overwrite.id)) {
|
|
463
|
+
allow |= bits(overwrite.allow);
|
|
464
|
+
deny |= bits(overwrite.deny);
|
|
465
|
+
}
|
|
466
|
+
base = base & ~deny | allow;
|
|
467
|
+
const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
|
|
468
|
+
if (member)
|
|
469
|
+
base = base & ~bits(member.deny) | bits(member.allow);
|
|
470
|
+
return new PermissionSet(base);
|
|
471
|
+
}
|
|
422
472
|
// packages/core/src/events.ts
|
|
423
473
|
var ClientEvent;
|
|
424
474
|
((ClientEvent) => {
|
|
@@ -455,6 +505,13 @@ var ClientEvent;
|
|
|
455
505
|
ClientEvent["GuildRoleDelete"] = "guildRoleDelete";
|
|
456
506
|
ClientEvent["GuildEmojisUpdate"] = "guildEmojisUpdate";
|
|
457
507
|
ClientEvent["GuildStickersUpdate"] = "guildStickersUpdate";
|
|
508
|
+
ClientEvent["EntitlementCreate"] = "entitlementCreate";
|
|
509
|
+
ClientEvent["EntitlementUpdate"] = "entitlementUpdate";
|
|
510
|
+
ClientEvent["EntitlementDelete"] = "entitlementDelete";
|
|
511
|
+
ClientEvent["SoundboardSoundCreate"] = "soundboardSoundCreate";
|
|
512
|
+
ClientEvent["SoundboardSoundUpdate"] = "soundboardSoundUpdate";
|
|
513
|
+
ClientEvent["SoundboardSoundDelete"] = "soundboardSoundDelete";
|
|
514
|
+
ClientEvent["SoundboardSoundsUpdate"] = "soundboardSoundsUpdate";
|
|
458
515
|
ClientEvent["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
|
|
459
516
|
ClientEvent["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
|
|
460
517
|
ClientEvent["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
|
|
@@ -497,6 +554,9 @@ class Collector extends EventEmitter {
|
|
|
497
554
|
endReason;
|
|
498
555
|
totalProcessed = 0;
|
|
499
556
|
#timeoutTimer;
|
|
557
|
+
#idleTimer;
|
|
558
|
+
#onAbort = () => this.stop("abort");
|
|
559
|
+
#cleanup = [];
|
|
500
560
|
constructor(options = {}) {
|
|
501
561
|
super();
|
|
502
562
|
this.options = options;
|
|
@@ -505,6 +565,27 @@ class Collector extends EventEmitter {
|
|
|
505
565
|
this.stop("time");
|
|
506
566
|
}, options.time);
|
|
507
567
|
}
|
|
568
|
+
this.#resetIdle();
|
|
569
|
+
if (options.signal?.aborted)
|
|
570
|
+
this.stop("abort");
|
|
571
|
+
else
|
|
572
|
+
options.signal?.addEventListener("abort", this.#onAbort, {
|
|
573
|
+
once: true
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
onDispose(cleanup) {
|
|
577
|
+
if (this.ended)
|
|
578
|
+
cleanup();
|
|
579
|
+
else
|
|
580
|
+
this.#cleanup.push(cleanup);
|
|
581
|
+
return this;
|
|
582
|
+
}
|
|
583
|
+
#resetIdle() {
|
|
584
|
+
if (!this.options.idle || this.options.idle <= 0)
|
|
585
|
+
return;
|
|
586
|
+
if (this.#idleTimer)
|
|
587
|
+
clearTimeout(this.#idleTimer);
|
|
588
|
+
this.#idleTimer = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
508
589
|
}
|
|
509
590
|
async handle(key, item) {
|
|
510
591
|
if (this.ended)
|
|
@@ -522,6 +603,7 @@ class Collector extends EventEmitter {
|
|
|
522
603
|
return false;
|
|
523
604
|
}
|
|
524
605
|
this.collected.set(key, item);
|
|
606
|
+
this.#resetIdle();
|
|
525
607
|
this.emit("collect", item);
|
|
526
608
|
if (this.options.max && this.collected.size >= this.options.max) {
|
|
527
609
|
this.stop("limit");
|
|
@@ -540,9 +622,53 @@ class Collector extends EventEmitter {
|
|
|
540
622
|
this.endReason = reason;
|
|
541
623
|
if (this.#timeoutTimer)
|
|
542
624
|
clearTimeout(this.#timeoutTimer);
|
|
625
|
+
if (this.#idleTimer)
|
|
626
|
+
clearTimeout(this.#idleTimer);
|
|
627
|
+
this.options.signal?.removeEventListener("abort", this.#onAbort);
|
|
628
|
+
for (const cleanup of this.#cleanup.splice(0)) {
|
|
629
|
+
try {
|
|
630
|
+
cleanup();
|
|
631
|
+
} catch {}
|
|
632
|
+
}
|
|
543
633
|
this.emit("end", this.collected, reason);
|
|
544
634
|
this.removeAllListeners();
|
|
545
635
|
}
|
|
636
|
+
wait() {
|
|
637
|
+
if (this.ended)
|
|
638
|
+
return Promise.resolve(this.collected);
|
|
639
|
+
return new Promise((resolve) => this.once("end", (collected) => resolve(collected)));
|
|
640
|
+
}
|
|
641
|
+
async* [Symbol.asyncIterator]() {
|
|
642
|
+
const queue = [];
|
|
643
|
+
let wake;
|
|
644
|
+
const onCollect = (item) => {
|
|
645
|
+
queue.push(item);
|
|
646
|
+
wake?.();
|
|
647
|
+
};
|
|
648
|
+
const onEnd = () => wake?.();
|
|
649
|
+
if (!this.ended) {
|
|
650
|
+
this.on("collect", onCollect);
|
|
651
|
+
this.on("end", onEnd);
|
|
652
|
+
}
|
|
653
|
+
try {
|
|
654
|
+
for (;; ) {
|
|
655
|
+
if (queue.length > 0) {
|
|
656
|
+
yield queue.shift();
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
if (this.ended)
|
|
660
|
+
return;
|
|
661
|
+
await new Promise((resolve) => wake = resolve);
|
|
662
|
+
wake = undefined;
|
|
663
|
+
}
|
|
664
|
+
} finally {
|
|
665
|
+
this.off("collect", onCollect);
|
|
666
|
+
this.off("end", onEnd);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
[Symbol.dispose]() {
|
|
670
|
+
this.stop("disposed");
|
|
671
|
+
}
|
|
546
672
|
next() {
|
|
547
673
|
return new Promise((resolve, reject) => {
|
|
548
674
|
if (this.ended) {
|
|
@@ -686,7 +812,340 @@ var InteractionResponseType = {
|
|
|
686
812
|
Modal: 9
|
|
687
813
|
};
|
|
688
814
|
// packages/collection/src/index.ts
|
|
815
|
+
class RecencyList {
|
|
816
|
+
#nodes = new Map;
|
|
817
|
+
#oldest;
|
|
818
|
+
#newest;
|
|
819
|
+
get size() {
|
|
820
|
+
return this.#nodes.size;
|
|
821
|
+
}
|
|
822
|
+
oldest() {
|
|
823
|
+
return this.#oldest?.key;
|
|
824
|
+
}
|
|
825
|
+
touch(key) {
|
|
826
|
+
const node = this.#nodes.get(key);
|
|
827
|
+
if (node)
|
|
828
|
+
return this.#moveNewest(node);
|
|
829
|
+
const created = { key, older: this.#newest };
|
|
830
|
+
if (this.#newest)
|
|
831
|
+
this.#newest.newer = created;
|
|
832
|
+
else
|
|
833
|
+
this.#oldest = created;
|
|
834
|
+
this.#newest = created;
|
|
835
|
+
this.#nodes.set(key, created);
|
|
836
|
+
}
|
|
837
|
+
promote(key) {
|
|
838
|
+
const node = this.#nodes.get(key);
|
|
839
|
+
if (node)
|
|
840
|
+
this.#moveNewest(node);
|
|
841
|
+
}
|
|
842
|
+
delete(key) {
|
|
843
|
+
const node = this.#nodes.get(key);
|
|
844
|
+
if (!node)
|
|
845
|
+
return false;
|
|
846
|
+
this.#unlink(node);
|
|
847
|
+
this.#nodes.delete(key);
|
|
848
|
+
return true;
|
|
849
|
+
}
|
|
850
|
+
clear() {
|
|
851
|
+
this.#nodes.clear();
|
|
852
|
+
this.#oldest = this.#newest = undefined;
|
|
853
|
+
}
|
|
854
|
+
#unlink(node) {
|
|
855
|
+
if (node.older)
|
|
856
|
+
node.older.newer = node.newer;
|
|
857
|
+
else
|
|
858
|
+
this.#oldest = node.newer;
|
|
859
|
+
if (node.newer)
|
|
860
|
+
node.newer.older = node.older;
|
|
861
|
+
else
|
|
862
|
+
this.#newest = node.older;
|
|
863
|
+
node.older = node.newer = undefined;
|
|
864
|
+
}
|
|
865
|
+
#moveNewest(node) {
|
|
866
|
+
if (node === this.#newest)
|
|
867
|
+
return;
|
|
868
|
+
this.#unlink(node);
|
|
869
|
+
node.older = this.#newest;
|
|
870
|
+
if (this.#newest)
|
|
871
|
+
this.#newest.newer = node;
|
|
872
|
+
else
|
|
873
|
+
this.#oldest = node;
|
|
874
|
+
this.#newest = node;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function assertTTL(ttl) {
|
|
878
|
+
if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
|
|
879
|
+
throw new RangeError("TTL must be a positive number, or omitted.");
|
|
880
|
+
}
|
|
881
|
+
|
|
689
882
|
class Collection extends Map {
|
|
883
|
+
#ttl;
|
|
884
|
+
#maxSize;
|
|
885
|
+
#onEvict;
|
|
886
|
+
#expiry = new Map;
|
|
887
|
+
#lru = new RecencyList;
|
|
888
|
+
#stats = {
|
|
889
|
+
hits: 0,
|
|
890
|
+
misses: 0,
|
|
891
|
+
expired: 0,
|
|
892
|
+
evicted: 0
|
|
893
|
+
};
|
|
894
|
+
#heap = [];
|
|
895
|
+
#timer;
|
|
896
|
+
#armedFor = Infinity;
|
|
897
|
+
constructor(entries, options = {}) {
|
|
898
|
+
super();
|
|
899
|
+
assertTTL(options.ttl);
|
|
900
|
+
if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
|
|
901
|
+
throw new RangeError("maxSize must be a positive integer.");
|
|
902
|
+
this.#ttl = options.ttl;
|
|
903
|
+
this.#maxSize = options.maxSize;
|
|
904
|
+
this.#onEvict = options.onEvict;
|
|
905
|
+
if (entries)
|
|
906
|
+
for (const [key, value] of entries)
|
|
907
|
+
this.set(key, value);
|
|
908
|
+
}
|
|
909
|
+
set(key, value, ttl) {
|
|
910
|
+
assertTTL(ttl);
|
|
911
|
+
const window = ttl ?? this.#ttl;
|
|
912
|
+
if (this.#maxSize !== undefined) {
|
|
913
|
+
this.#lru.touch(key);
|
|
914
|
+
}
|
|
915
|
+
super.set(key, value);
|
|
916
|
+
if (window !== undefined)
|
|
917
|
+
this.#schedule(key, window);
|
|
918
|
+
else if (this.#expiry.size > 0)
|
|
919
|
+
this.#expiry.delete(key);
|
|
920
|
+
this.#enforceCap();
|
|
921
|
+
return this;
|
|
922
|
+
}
|
|
923
|
+
setWithoutTTL(key, value) {
|
|
924
|
+
if (this.#expiry.size > 0)
|
|
925
|
+
this.#expiry.delete(key);
|
|
926
|
+
if (this.#lru.size > 0)
|
|
927
|
+
this.#lru.delete(key);
|
|
928
|
+
super.set(key, value);
|
|
929
|
+
return this;
|
|
930
|
+
}
|
|
931
|
+
get(key) {
|
|
932
|
+
if (this.#expireIfDue(key)) {
|
|
933
|
+
this.#stats.misses++;
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
const value = super.get(key);
|
|
937
|
+
if (value === undefined && !super.has(key)) {
|
|
938
|
+
this.#stats.misses++;
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
this.#stats.hits++;
|
|
942
|
+
const expiry = this.#expiry.get(key);
|
|
943
|
+
if (expiry)
|
|
944
|
+
expiry.deadline = Date.now() + expiry.window;
|
|
945
|
+
this.#lru.promote(key);
|
|
946
|
+
return value;
|
|
947
|
+
}
|
|
948
|
+
peek(key) {
|
|
949
|
+
if (!this.#expireIfDue(key) && super.has(key)) {
|
|
950
|
+
this.#stats.hits++;
|
|
951
|
+
return super.get(key);
|
|
952
|
+
}
|
|
953
|
+
this.#stats.misses++;
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
get stats() {
|
|
957
|
+
return { ...this.#stats };
|
|
958
|
+
}
|
|
959
|
+
has(key) {
|
|
960
|
+
return !this.#expireIfDue(key) && super.has(key);
|
|
961
|
+
}
|
|
962
|
+
delete(key) {
|
|
963
|
+
if (this.#expireIfDue(key))
|
|
964
|
+
return false;
|
|
965
|
+
this.#expiry.delete(key);
|
|
966
|
+
this.#lru.delete(key);
|
|
967
|
+
return super.delete(key);
|
|
968
|
+
}
|
|
969
|
+
clear() {
|
|
970
|
+
super.clear();
|
|
971
|
+
this.#expiry.clear();
|
|
972
|
+
this.#lru.clear();
|
|
973
|
+
this.#heap.length = 0;
|
|
974
|
+
if (this.#timer)
|
|
975
|
+
clearTimeout(this.#timer);
|
|
976
|
+
this.#timer = undefined;
|
|
977
|
+
this.#armedFor = Infinity;
|
|
978
|
+
}
|
|
979
|
+
get size() {
|
|
980
|
+
this.purge();
|
|
981
|
+
return super.size;
|
|
982
|
+
}
|
|
983
|
+
entries() {
|
|
984
|
+
this.purge();
|
|
985
|
+
return super.entries();
|
|
986
|
+
}
|
|
987
|
+
keys() {
|
|
988
|
+
this.purge();
|
|
989
|
+
return super.keys();
|
|
990
|
+
}
|
|
991
|
+
values() {
|
|
992
|
+
this.purge();
|
|
993
|
+
return super.values();
|
|
994
|
+
}
|
|
995
|
+
[Symbol.iterator]() {
|
|
996
|
+
return this.entries();
|
|
997
|
+
}
|
|
998
|
+
forEach(callback, thisArg) {
|
|
999
|
+
this.purge();
|
|
1000
|
+
super.forEach(callback, thisArg);
|
|
1001
|
+
}
|
|
1002
|
+
ttlRemaining(key) {
|
|
1003
|
+
if (this.#expireIfDue(key))
|
|
1004
|
+
return;
|
|
1005
|
+
const expiry = this.#expiry.get(key);
|
|
1006
|
+
return expiry && Math.max(0, expiry.deadline - Date.now());
|
|
1007
|
+
}
|
|
1008
|
+
purge() {
|
|
1009
|
+
if (this.#expiry.size === 0)
|
|
1010
|
+
return 0;
|
|
1011
|
+
const now = Date.now();
|
|
1012
|
+
let removed = 0;
|
|
1013
|
+
const dropped = [];
|
|
1014
|
+
while (this.#nextDeadline() <= now) {
|
|
1015
|
+
const due = this.#heapPop();
|
|
1016
|
+
dropped.push([due.key, super.get(due.key)]);
|
|
1017
|
+
this.#remove(due.key);
|
|
1018
|
+
removed++;
|
|
1019
|
+
}
|
|
1020
|
+
this.#stats.expired += removed;
|
|
1021
|
+
this.#rearm();
|
|
1022
|
+
for (const [key, value] of dropped)
|
|
1023
|
+
this.#notify(key, value, "expired");
|
|
1024
|
+
return removed;
|
|
1025
|
+
}
|
|
1026
|
+
#expireIfDue(key) {
|
|
1027
|
+
const expiry = this.#expiry.get(key);
|
|
1028
|
+
if (!expiry || expiry.deadline > Date.now())
|
|
1029
|
+
return false;
|
|
1030
|
+
const value = super.get(key);
|
|
1031
|
+
this.#remove(key);
|
|
1032
|
+
this.#stats.expired++;
|
|
1033
|
+
this.#notify(key, value, "expired");
|
|
1034
|
+
return true;
|
|
1035
|
+
}
|
|
1036
|
+
#remove(key) {
|
|
1037
|
+
this.#expiry.delete(key);
|
|
1038
|
+
this.#lru.delete(key);
|
|
1039
|
+
super.delete(key);
|
|
1040
|
+
}
|
|
1041
|
+
#notify(key, value, reason) {
|
|
1042
|
+
if (!this.#onEvict)
|
|
1043
|
+
return;
|
|
1044
|
+
try {
|
|
1045
|
+
this.#onEvict(key, value, reason);
|
|
1046
|
+
} catch {}
|
|
1047
|
+
}
|
|
1048
|
+
#enforceCap() {
|
|
1049
|
+
if (this.#maxSize === undefined)
|
|
1050
|
+
return;
|
|
1051
|
+
while (this.#lru.size > this.#maxSize) {
|
|
1052
|
+
const oldest = this.#lru.oldest();
|
|
1053
|
+
const value = super.get(oldest);
|
|
1054
|
+
this.#remove(oldest);
|
|
1055
|
+
this.#stats.evicted++;
|
|
1056
|
+
this.#notify(oldest, value, "evicted");
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
#schedule(key, window) {
|
|
1060
|
+
const deadline = Date.now() + window;
|
|
1061
|
+
const expiry = this.#expiry.get(key);
|
|
1062
|
+
if (expiry) {
|
|
1063
|
+
expiry.deadline = deadline;
|
|
1064
|
+
expiry.window = window;
|
|
1065
|
+
if (deadline >= expiry.filed)
|
|
1066
|
+
return;
|
|
1067
|
+
expiry.filed = deadline;
|
|
1068
|
+
} else
|
|
1069
|
+
this.#expiry.set(key, { deadline, window, filed: deadline });
|
|
1070
|
+
this.#heapPush({ key, deadline });
|
|
1071
|
+
if (this.#heap.length > 2 * this.#expiry.size + 8)
|
|
1072
|
+
this.#compact();
|
|
1073
|
+
this.#rearm();
|
|
1074
|
+
}
|
|
1075
|
+
#nextDeadline() {
|
|
1076
|
+
for (;; ) {
|
|
1077
|
+
const top = this.#heap[0];
|
|
1078
|
+
if (top === undefined)
|
|
1079
|
+
return Infinity;
|
|
1080
|
+
const expiry = this.#expiry.get(top.key);
|
|
1081
|
+
if (!expiry || expiry.filed !== top.deadline) {
|
|
1082
|
+
this.#heapPop();
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
if (expiry.deadline === top.deadline)
|
|
1086
|
+
return top.deadline;
|
|
1087
|
+
this.#heapPop();
|
|
1088
|
+
expiry.filed = expiry.deadline;
|
|
1089
|
+
this.#heapPush({ key: top.key, deadline: expiry.deadline });
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
#compact() {
|
|
1093
|
+
const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
|
|
1094
|
+
this.#heap.length = 0;
|
|
1095
|
+
for (const record of live)
|
|
1096
|
+
this.#heapPush(record);
|
|
1097
|
+
}
|
|
1098
|
+
#rearm() {
|
|
1099
|
+
const deadline = this.#nextDeadline();
|
|
1100
|
+
if (this.#timer !== undefined && deadline >= this.#armedFor)
|
|
1101
|
+
return;
|
|
1102
|
+
if (this.#timer)
|
|
1103
|
+
clearTimeout(this.#timer);
|
|
1104
|
+
this.#timer = undefined;
|
|
1105
|
+
this.#armedFor = deadline;
|
|
1106
|
+
if (deadline === Infinity)
|
|
1107
|
+
return;
|
|
1108
|
+
this.#timer = setTimeout(() => {
|
|
1109
|
+
this.#timer = undefined;
|
|
1110
|
+
this.#armedFor = Infinity;
|
|
1111
|
+
this.purge();
|
|
1112
|
+
}, Math.max(0, deadline - Date.now()));
|
|
1113
|
+
this.#timer.unref?.();
|
|
1114
|
+
}
|
|
1115
|
+
#heapPush(record) {
|
|
1116
|
+
const heap = this.#heap;
|
|
1117
|
+
heap.push(record);
|
|
1118
|
+
let i = heap.length - 1;
|
|
1119
|
+
while (i > 0) {
|
|
1120
|
+
const parent = i - 1 >> 1;
|
|
1121
|
+
if (heap[parent].deadline <= heap[i].deadline)
|
|
1122
|
+
break;
|
|
1123
|
+
[heap[parent], heap[i]] = [heap[i], heap[parent]];
|
|
1124
|
+
i = parent;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
#heapPop() {
|
|
1128
|
+
const heap = this.#heap;
|
|
1129
|
+
const top = heap[0];
|
|
1130
|
+
const last = heap.pop();
|
|
1131
|
+
if (top === undefined || heap.length === 0)
|
|
1132
|
+
return top;
|
|
1133
|
+
heap[0] = last;
|
|
1134
|
+
for (let i = 0;; ) {
|
|
1135
|
+
const left = 2 * i + 1;
|
|
1136
|
+
const right = left + 1;
|
|
1137
|
+
let smallest = i;
|
|
1138
|
+
if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
|
|
1139
|
+
smallest = left;
|
|
1140
|
+
if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
|
|
1141
|
+
smallest = right;
|
|
1142
|
+
if (smallest === i)
|
|
1143
|
+
break;
|
|
1144
|
+
[heap[smallest], heap[i]] = [heap[i], heap[smallest]];
|
|
1145
|
+
i = smallest;
|
|
1146
|
+
}
|
|
1147
|
+
return top;
|
|
1148
|
+
}
|
|
690
1149
|
first() {
|
|
691
1150
|
for (const value of this.values())
|
|
692
1151
|
return value;
|
|
@@ -911,11 +1370,40 @@ class Manager {
|
|
|
911
1370
|
has(id) {
|
|
912
1371
|
return this.cache.has(id);
|
|
913
1372
|
}
|
|
1373
|
+
#inflight = new Map;
|
|
1374
|
+
fetchOnce(id, load, store = (value) => {
|
|
1375
|
+
this.set(id, value);
|
|
1376
|
+
return value;
|
|
1377
|
+
}) {
|
|
1378
|
+
const pending = this.#inflight.get(id);
|
|
1379
|
+
if (pending)
|
|
1380
|
+
return pending.promise;
|
|
1381
|
+
const entry = {
|
|
1382
|
+
promise: new Promise((resolve) => resolve(load())),
|
|
1383
|
+
dirty: false
|
|
1384
|
+
};
|
|
1385
|
+
this.#inflight.set(id, entry);
|
|
1386
|
+
entry.promise = entry.promise.then((value) => {
|
|
1387
|
+
this.#inflight.delete(id);
|
|
1388
|
+
return entry.dirty ? this.get(id) ?? value : store(value);
|
|
1389
|
+
}, (error) => {
|
|
1390
|
+
this.#inflight.delete(id);
|
|
1391
|
+
throw error;
|
|
1392
|
+
});
|
|
1393
|
+
return entry.promise;
|
|
1394
|
+
}
|
|
1395
|
+
#markDirty(id) {
|
|
1396
|
+
const pending = this.#inflight.get(id);
|
|
1397
|
+
if (pending)
|
|
1398
|
+
pending.dirty = true;
|
|
1399
|
+
}
|
|
914
1400
|
set(id, value) {
|
|
915
|
-
this
|
|
1401
|
+
this.#markDirty(id);
|
|
1402
|
+
this.cache.setWithoutTTL(id, value);
|
|
916
1403
|
return this;
|
|
917
1404
|
}
|
|
918
1405
|
delete(id) {
|
|
1406
|
+
this.#markDirty(id);
|
|
919
1407
|
return this.cache.delete(id);
|
|
920
1408
|
}
|
|
921
1409
|
clear() {
|
|
@@ -951,16 +1439,20 @@ class ResourceManager extends Manager {
|
|
|
951
1439
|
async resolve(id) {
|
|
952
1440
|
return this.get(id) ?? this.fetch(id);
|
|
953
1441
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
this.set(id, resource);
|
|
957
|
-
return resource;
|
|
1442
|
+
fetch(id) {
|
|
1443
|
+
return this.fetchOnce(id, () => this.#fetcher(id));
|
|
958
1444
|
}
|
|
959
1445
|
async fetchMany(ids) {
|
|
960
1446
|
return Promise.all([...ids].map((id) => this.resolve(id)));
|
|
961
1447
|
}
|
|
962
1448
|
upsert(resource) {
|
|
963
1449
|
const key = this.#key(resource);
|
|
1450
|
+
const existing = this.get(key);
|
|
1451
|
+
if (existing !== undefined && existing !== resource && typeof existing === "object" && existing !== null) {
|
|
1452
|
+
Object.assign(existing, resource);
|
|
1453
|
+
this.set(key, existing);
|
|
1454
|
+
return existing;
|
|
1455
|
+
}
|
|
964
1456
|
this.set(key, resource);
|
|
965
1457
|
return resource;
|
|
966
1458
|
}
|
|
@@ -971,7 +1463,7 @@ class ResourceManager extends Manager {
|
|
|
971
1463
|
// packages/rest/package.json
|
|
972
1464
|
var package_default = {
|
|
973
1465
|
name: "@lunibee/rest",
|
|
974
|
-
version: "0.1
|
|
1466
|
+
version: "0.2.1",
|
|
975
1467
|
type: "module",
|
|
976
1468
|
module: "./src/index.ts",
|
|
977
1469
|
types: "./src/index.ts",
|
|
@@ -1031,7 +1523,29 @@ class MemoryRateLimitStore {
|
|
|
1031
1523
|
}
|
|
1032
1524
|
|
|
1033
1525
|
// packages/rest/src/errors.ts
|
|
1526
|
+
function kindFromStatus(status) {
|
|
1527
|
+
if (status === 429)
|
|
1528
|
+
return "rateLimited";
|
|
1529
|
+
if (status === 401)
|
|
1530
|
+
return "authentication";
|
|
1531
|
+
if (status === 403)
|
|
1532
|
+
return "permission";
|
|
1533
|
+
if (status === 404)
|
|
1534
|
+
return "notFound";
|
|
1535
|
+
if (status === 400 || status === 422)
|
|
1536
|
+
return "validation";
|
|
1537
|
+
if (status >= 500)
|
|
1538
|
+
return "server";
|
|
1539
|
+
if (status === 0)
|
|
1540
|
+
return "network";
|
|
1541
|
+
return "client";
|
|
1542
|
+
}
|
|
1543
|
+
function redactPath(path) {
|
|
1544
|
+
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/, "$1:token");
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1034
1547
|
class RESTError extends Error {
|
|
1548
|
+
kind;
|
|
1035
1549
|
status;
|
|
1036
1550
|
code;
|
|
1037
1551
|
errors;
|
|
@@ -1041,14 +1555,18 @@ class RESTError extends Error {
|
|
|
1041
1555
|
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
1042
1556
|
this.name = "RESTError";
|
|
1043
1557
|
this.status = status;
|
|
1558
|
+
this.kind = options.kind ?? kindFromStatus(status);
|
|
1044
1559
|
this.code = code;
|
|
1045
1560
|
this.errors = errors;
|
|
1046
1561
|
this.method = options.method;
|
|
1047
|
-
this.path = options.path;
|
|
1562
|
+
this.path = options.path === undefined ? undefined : redactPath(options.path);
|
|
1563
|
+
}
|
|
1564
|
+
get retryable() {
|
|
1565
|
+
return this.kind === "rateLimited" || this.kind === "server" || this.kind === "network" || this.kind === "timeout";
|
|
1048
1566
|
}
|
|
1049
1567
|
}
|
|
1050
1568
|
function abortError(path, reason) {
|
|
1051
|
-
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason });
|
|
1569
|
+
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason, kind: "aborted" });
|
|
1052
1570
|
}
|
|
1053
1571
|
async function sleep(delay, signal, path) {
|
|
1054
1572
|
if (delay <= 0)
|
|
@@ -1383,8 +1901,23 @@ var Routes = {
|
|
|
1383
1901
|
invite: (code) => `/invites/${encodeURIComponent(code)}`,
|
|
1384
1902
|
guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
|
|
1385
1903
|
guildEmoji: (guildId, emojiId) => emojiId ? `/guilds/${snowflake(guildId, "Guild ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/emojis`,
|
|
1386
|
-
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis
|
|
1904
|
+
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`,
|
|
1905
|
+
pollExpire: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/expire`,
|
|
1906
|
+
pollAnswerVoters: (channelId, messageId, answerId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/answers/${integer(answerId, "Answer ID")}`,
|
|
1907
|
+
guildSticker: (guildId, stickerId) => stickerId ? `/guilds/${snowflake(guildId, "Guild ID")}/stickers/${snowflake(stickerId, "Sticker ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/stickers`,
|
|
1908
|
+
sendSoundboardSound: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/send-soundboard-sound`,
|
|
1909
|
+
soundboardDefaultSounds: () => "/soundboard-default-sounds",
|
|
1910
|
+
guildSoundboardSound: (guildId, soundId) => soundId ? `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds/${snowflake(soundId, "Sound ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds`,
|
|
1911
|
+
applicationSkus: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/skus`,
|
|
1912
|
+
applicationEntitlement: (applicationId, entitlementId) => entitlementId ? `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/entitlements`,
|
|
1913
|
+
consumeEntitlement: (applicationId, entitlementId) => `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}/consume`,
|
|
1914
|
+
skuSubscription: (skuId, subscriptionId) => subscriptionId ? `/skus/${snowflake(skuId, "SKU ID")}/subscriptions/${snowflake(subscriptionId, "Subscription ID")}` : `/skus/${snowflake(skuId, "SKU ID")}/subscriptions`
|
|
1387
1915
|
};
|
|
1916
|
+
function integer(value, field) {
|
|
1917
|
+
if (!Number.isInteger(value) || value < 0)
|
|
1918
|
+
throw new TypeError(`${field} must be a non-negative integer.`);
|
|
1919
|
+
return String(value);
|
|
1920
|
+
}
|
|
1388
1921
|
function snowflake(value, field) {
|
|
1389
1922
|
if (!/^\d{1,20}$/.test(value))
|
|
1390
1923
|
throw new TypeError(`${field} must be a valid Discord snowflake.`);
|
|
@@ -1521,7 +2054,8 @@ class REST {
|
|
|
1521
2054
|
throw new RESTError(failure.message, 0, undefined, undefined, {
|
|
1522
2055
|
method,
|
|
1523
2056
|
path,
|
|
1524
|
-
cause: failure.cause ?? failure
|
|
2057
|
+
cause: failure.cause ?? failure,
|
|
2058
|
+
kind: failure.timedOut ? "timeout" : "network"
|
|
1525
2059
|
});
|
|
1526
2060
|
}
|
|
1527
2061
|
this.#emit(this.#hooks.onResponse, {
|
|
@@ -1620,6 +2154,9 @@ class REST {
|
|
|
1620
2154
|
#emit(hook, ctx) {
|
|
1621
2155
|
if (!hook)
|
|
1622
2156
|
return;
|
|
2157
|
+
const withPath = ctx;
|
|
2158
|
+
if (typeof withPath.path === "string")
|
|
2159
|
+
ctx = { ...ctx, path: redactPath(withPath.path) };
|
|
1623
2160
|
Promise.resolve().then(() => hook(ctx)).catch(() => {});
|
|
1624
2161
|
}
|
|
1625
2162
|
}
|
|
@@ -1696,6 +2233,7 @@ class Channel extends BaseStructure {
|
|
|
1696
2233
|
nsfw;
|
|
1697
2234
|
rateLimitPerUser;
|
|
1698
2235
|
position;
|
|
2236
|
+
permissionOverwrites;
|
|
1699
2237
|
#context;
|
|
1700
2238
|
constructor(data, context) {
|
|
1701
2239
|
super(data.id);
|
|
@@ -1709,6 +2247,7 @@ class Channel extends BaseStructure {
|
|
|
1709
2247
|
this.nsfw = data.nsfw;
|
|
1710
2248
|
this.rateLimitPerUser = data.rate_limit_per_user;
|
|
1711
2249
|
this.position = data.position;
|
|
2250
|
+
this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
|
|
1712
2251
|
this.#context = context;
|
|
1713
2252
|
}
|
|
1714
2253
|
sendMessage(options) {
|
|
@@ -1732,6 +2271,11 @@ class Channel extends BaseStructure {
|
|
|
1732
2271
|
editTopic(topic) {
|
|
1733
2272
|
return this.edit({ topic });
|
|
1734
2273
|
}
|
|
2274
|
+
editPermissionOverwrite(targetId, changes, options) {
|
|
2275
|
+
if (!this.#context?.editPermissionOverwrite)
|
|
2276
|
+
throw new Error("This channel is not attached to a client.");
|
|
2277
|
+
return this.#context.editPermissionOverwrite(this.id, targetId, changes, options);
|
|
2278
|
+
}
|
|
1735
2279
|
editParent(parentId) {
|
|
1736
2280
|
return this.edit({ parent_id: parentId });
|
|
1737
2281
|
}
|
|
@@ -1866,7 +2410,148 @@ class Guild extends BaseStructure {
|
|
|
1866
2410
|
return this.name;
|
|
1867
2411
|
}
|
|
1868
2412
|
}
|
|
2413
|
+
|
|
1869
2414
|
// packages/structures/src/resources.ts
|
|
2415
|
+
function toDateOrNull(value) {
|
|
2416
|
+
if (!value)
|
|
2417
|
+
return null;
|
|
2418
|
+
const date = new Date(value);
|
|
2419
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
class GuildMember {
|
|
2423
|
+
user;
|
|
2424
|
+
guildId;
|
|
2425
|
+
nickname;
|
|
2426
|
+
roleIds;
|
|
2427
|
+
pending;
|
|
2428
|
+
joinedAt;
|
|
2429
|
+
avatarHash;
|
|
2430
|
+
premiumSince;
|
|
2431
|
+
timedOutUntil;
|
|
2432
|
+
flags;
|
|
2433
|
+
#suppliedPermissions;
|
|
2434
|
+
#context;
|
|
2435
|
+
constructor(data, context) {
|
|
2436
|
+
this.user = new User(data.user);
|
|
2437
|
+
this.#context = context;
|
|
2438
|
+
if (!/^\d{1,20}$/.test(data.guild_id))
|
|
2439
|
+
throw new TypeError("Member guild_id must be a valid snowflake.");
|
|
2440
|
+
this.guildId = data.guild_id;
|
|
2441
|
+
this.nickname = data.nick ?? null;
|
|
2442
|
+
this.roleIds = [...data.roles ?? []];
|
|
2443
|
+
this.pending = data.pending ?? false;
|
|
2444
|
+
this.joinedAt = data.joined_at ? new Date(data.joined_at) : undefined;
|
|
2445
|
+
if (this.joinedAt?.toString() === "Invalid Date")
|
|
2446
|
+
throw new RangeError("Member joined_at must be a valid date.");
|
|
2447
|
+
if (data.permissions !== undefined)
|
|
2448
|
+
this.#suppliedPermissions = new PermissionsBitField(data.permissions);
|
|
2449
|
+
this.avatarHash = data.avatar ?? null;
|
|
2450
|
+
this.premiumSince = toDateOrNull(data.premium_since);
|
|
2451
|
+
this.timedOutUntil = toDateOrNull(data.communication_disabled_until);
|
|
2452
|
+
this.flags = data.flags ?? 0;
|
|
2453
|
+
}
|
|
2454
|
+
get permissions() {
|
|
2455
|
+
if (this.#suppliedPermissions)
|
|
2456
|
+
return this.#suppliedPermissions;
|
|
2457
|
+
return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds) ?? 0n);
|
|
2458
|
+
}
|
|
2459
|
+
permissionsIn(channelId) {
|
|
2460
|
+
const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId);
|
|
2461
|
+
return computed ? new PermissionsBitField(computed) : null;
|
|
2462
|
+
}
|
|
2463
|
+
#action(name) {
|
|
2464
|
+
const action = this.#context?.[name];
|
|
2465
|
+
if (!action)
|
|
2466
|
+
throw new Error("This member is not attached to a client.");
|
|
2467
|
+
return action;
|
|
2468
|
+
}
|
|
2469
|
+
kick(reason) {
|
|
2470
|
+
return this.#action("kickMember")(this.guildId, this.user.id, reason);
|
|
2471
|
+
}
|
|
2472
|
+
ban(options = {}) {
|
|
2473
|
+
return this.#action("banMember")(this.guildId, this.user.id, options);
|
|
2474
|
+
}
|
|
2475
|
+
edit(options, reason) {
|
|
2476
|
+
return this.#action("editMember")(this.guildId, this.user.id, options, reason);
|
|
2477
|
+
}
|
|
2478
|
+
timeout(milliseconds, reason) {
|
|
2479
|
+
if (milliseconds !== null && !(milliseconds > 0))
|
|
2480
|
+
throw new RangeError("Timeout length must be a positive number of milliseconds.");
|
|
2481
|
+
return this.edit({
|
|
2482
|
+
communication_disabled_until: milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString()
|
|
2483
|
+
}, reason);
|
|
2484
|
+
}
|
|
2485
|
+
setNickname(nickname, reason) {
|
|
2486
|
+
return this.edit({ nick: nickname }, reason);
|
|
2487
|
+
}
|
|
2488
|
+
addRole(roleId, reason) {
|
|
2489
|
+
return this.#action("addMemberRole")(this.guildId, this.user.id, roleId, reason);
|
|
2490
|
+
}
|
|
2491
|
+
removeRole(roleId, reason) {
|
|
2492
|
+
return this.#action("removeMemberRole")(this.guildId, this.user.id, roleId, reason);
|
|
2493
|
+
}
|
|
2494
|
+
get displayName() {
|
|
2495
|
+
return this.nickname ?? this.user.displayName;
|
|
2496
|
+
}
|
|
2497
|
+
get isTimedOut() {
|
|
2498
|
+
return this.timedOutUntil !== null && this.timedOutUntil > new Date;
|
|
2499
|
+
}
|
|
2500
|
+
avatarURL(options = {}) {
|
|
2501
|
+
if (this.avatarHash)
|
|
2502
|
+
return cdnURL(`/guilds/${this.guildId}/users/${this.user.id}/avatars`, this.avatarHash, options);
|
|
2503
|
+
return this.user.avatarURL(options);
|
|
2504
|
+
}
|
|
2505
|
+
displayAvatarURL(options = {}) {
|
|
2506
|
+
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
|
|
2507
|
+
}
|
|
2508
|
+
toString() {
|
|
2509
|
+
return this.user.toString();
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
class Role extends BaseStructure {
|
|
2514
|
+
name;
|
|
2515
|
+
color;
|
|
2516
|
+
hoist;
|
|
2517
|
+
permissions;
|
|
2518
|
+
managed;
|
|
2519
|
+
mentionable;
|
|
2520
|
+
position;
|
|
2521
|
+
unicodeEmoji;
|
|
2522
|
+
iconHash;
|
|
2523
|
+
tags;
|
|
2524
|
+
constructor(data) {
|
|
2525
|
+
super(data.id);
|
|
2526
|
+
if (!data.name)
|
|
2527
|
+
throw new TypeError("Role name cannot be empty.");
|
|
2528
|
+
this.name = data.name;
|
|
2529
|
+
this.color = data.color ?? 0;
|
|
2530
|
+
this.hoist = data.hoist ?? false;
|
|
2531
|
+
this.permissions = new PermissionsBitField(data.permissions ?? 0n);
|
|
2532
|
+
this.managed = data.managed ?? false;
|
|
2533
|
+
this.mentionable = data.mentionable ?? false;
|
|
2534
|
+
this.position = data.position ?? 0;
|
|
2535
|
+
this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
2536
|
+
this.iconHash = data.icon ?? null;
|
|
2537
|
+
this.tags = data.tags ?? null;
|
|
2538
|
+
}
|
|
2539
|
+
get colorHex() {
|
|
2540
|
+
return `#${this.color.toString(16).padStart(6, "0").toUpperCase()}`;
|
|
2541
|
+
}
|
|
2542
|
+
iconURL(options = {}) {
|
|
2543
|
+
if (!this.iconHash)
|
|
2544
|
+
return null;
|
|
2545
|
+
return cdnURL(`/role-icons/${this.id}`, this.iconHash, options);
|
|
2546
|
+
}
|
|
2547
|
+
isEveryone(guildId) {
|
|
2548
|
+
return this.id === guildId;
|
|
2549
|
+
}
|
|
2550
|
+
toString() {
|
|
2551
|
+
return `<@&${this.id}>`;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
|
|
1870
2555
|
class TextChannel extends Channel {
|
|
1871
2556
|
constructor(data, context) {
|
|
1872
2557
|
super(data, context);
|
|
@@ -1875,6 +2560,38 @@ class TextChannel extends Channel {
|
|
|
1875
2560
|
return `<#${this.id}>`;
|
|
1876
2561
|
}
|
|
1877
2562
|
}
|
|
2563
|
+
class Emoji extends BaseStructure {
|
|
2564
|
+
name;
|
|
2565
|
+
roleIds;
|
|
2566
|
+
user;
|
|
2567
|
+
requireColons;
|
|
2568
|
+
managed;
|
|
2569
|
+
animated;
|
|
2570
|
+
available;
|
|
2571
|
+
constructor(data) {
|
|
2572
|
+
super(data.id ?? "0");
|
|
2573
|
+
if (data.id === null)
|
|
2574
|
+
this.id = "unicode";
|
|
2575
|
+
this.name = data.name;
|
|
2576
|
+
this.roleIds = data.roles ?? [];
|
|
2577
|
+
this.user = data.user ? new User(data.user) : null;
|
|
2578
|
+
this.requireColons = data.require_colons ?? false;
|
|
2579
|
+
this.managed = data.managed ?? false;
|
|
2580
|
+
this.animated = data.animated ?? false;
|
|
2581
|
+
this.available = data.available ?? true;
|
|
2582
|
+
}
|
|
2583
|
+
url(options = {}) {
|
|
2584
|
+
if (!this.id || this.id === "unicode")
|
|
2585
|
+
return null;
|
|
2586
|
+
const ext = options.extension ?? (this.animated ? "gif" : "png");
|
|
2587
|
+
const size = options.size ? `?size=${options.size}` : "";
|
|
2588
|
+
return `${CDN_BASE}/emojis/${this.id}.${ext}${size}`;
|
|
2589
|
+
}
|
|
2590
|
+
toString() {
|
|
2591
|
+
return this.id !== "unicode" ? `<${this.animated ? "a" : ""}:${this.name}:${this.id}>` : this.name ?? "";
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
|
|
1878
2595
|
class AutoModerationRule extends BaseStructure {
|
|
1879
2596
|
guildId;
|
|
1880
2597
|
name;
|
|
@@ -2167,6 +2884,17 @@ class CommandOptions {
|
|
|
2167
2884
|
throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
|
|
2168
2885
|
return resolved;
|
|
2169
2886
|
}
|
|
2887
|
+
getMentionableType(name) {
|
|
2888
|
+
const opt = this.#get(name);
|
|
2889
|
+
if (!opt || opt.type !== OptionType.Mentionable)
|
|
2890
|
+
return null;
|
|
2891
|
+
const id = String(opt.value);
|
|
2892
|
+
if (this.#resolved?.users?.[id])
|
|
2893
|
+
return "user";
|
|
2894
|
+
if (this.#resolved?.roles?.[id])
|
|
2895
|
+
return "role";
|
|
2896
|
+
return null;
|
|
2897
|
+
}
|
|
2170
2898
|
getAttachment(name, required = false) {
|
|
2171
2899
|
const opt = this.#get(name);
|
|
2172
2900
|
if (!opt || opt.type !== OptionType.Attachment) {
|
|
@@ -2192,6 +2920,17 @@ var InteractionType = {
|
|
|
2192
2920
|
ApplicationCommandAutocomplete: 4,
|
|
2193
2921
|
ModalSubmit: 5
|
|
2194
2922
|
};
|
|
2923
|
+
var EPHEMERAL = 64;
|
|
2924
|
+
var TOKEN_LIFETIME_MS = 15 * 60000;
|
|
2925
|
+
var DISCORD_EPOCH = 1420070400000n;
|
|
2926
|
+
function toMessageData(options) {
|
|
2927
|
+
if (typeof options === "string")
|
|
2928
|
+
return { content: options };
|
|
2929
|
+
const { ephemeral, ...data } = options;
|
|
2930
|
+
if (ephemeral)
|
|
2931
|
+
data.flags = (typeof data.flags === "number" ? data.flags : 0) | EPHEMERAL;
|
|
2932
|
+
return data;
|
|
2933
|
+
}
|
|
2195
2934
|
|
|
2196
2935
|
class InteractionResponse {
|
|
2197
2936
|
type;
|
|
@@ -2206,14 +2945,10 @@ class InteractionResponse {
|
|
|
2206
2945
|
return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
|
|
2207
2946
|
}
|
|
2208
2947
|
static message(options) {
|
|
2209
|
-
|
|
2210
|
-
if (options.ephemeral) {
|
|
2211
|
-
data.flags = (typeof options.flags === "number" ? options.flags : 0) | 64;
|
|
2212
|
-
}
|
|
2213
|
-
return new InteractionResponse(InteractionResponseType.ChannelMessage, data);
|
|
2948
|
+
return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
|
|
2214
2949
|
}
|
|
2215
2950
|
static defer(ephemeral = false) {
|
|
2216
|
-
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags:
|
|
2951
|
+
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
|
|
2217
2952
|
}
|
|
2218
2953
|
static pong() {
|
|
2219
2954
|
return new InteractionResponse(InteractionResponseType.Pong);
|
|
@@ -2231,6 +2966,7 @@ class Interaction {
|
|
|
2231
2966
|
replied = false;
|
|
2232
2967
|
deferred = false;
|
|
2233
2968
|
#client;
|
|
2969
|
+
#acknowledging = false;
|
|
2234
2970
|
constructor(client, data) {
|
|
2235
2971
|
if (!data.id || !data.token)
|
|
2236
2972
|
throw new TypeError("Interaction ID and token are required.");
|
|
@@ -2246,6 +2982,20 @@ class Interaction {
|
|
|
2246
2982
|
isChatInputCommand() {
|
|
2247
2983
|
return this.type === InteractionType.ApplicationCommand;
|
|
2248
2984
|
}
|
|
2985
|
+
awaitModalSubmit(options) {
|
|
2986
|
+
const collect = this.#client.resourceContext?.collectInteractions;
|
|
2987
|
+
if (!collect)
|
|
2988
|
+
return Promise.reject(new Error("This interaction is not attached to a client."));
|
|
2989
|
+
if (!(options.time > 0))
|
|
2990
|
+
return Promise.reject(new RangeError("awaitModalSubmit needs a positive time."));
|
|
2991
|
+
const userId = this.user?.id;
|
|
2992
|
+
const collector = collect({
|
|
2993
|
+
time: options.time,
|
|
2994
|
+
max: 1,
|
|
2995
|
+
filter: async (interaction) => interaction.isModalSubmit() && interaction.user?.id === userId && (options.customId === undefined || interaction.customId === options.customId) && (options.filter ? await options.filter(interaction) : true)
|
|
2996
|
+
});
|
|
2997
|
+
return collector.next();
|
|
2998
|
+
}
|
|
2249
2999
|
isMessageComponent() {
|
|
2250
3000
|
return this.type === InteractionType.MessageComponent;
|
|
2251
3001
|
}
|
|
@@ -2280,9 +3030,57 @@ class Interaction {
|
|
|
2280
3030
|
return [3, 5, 6, 7, 8].includes(this.#componentType());
|
|
2281
3031
|
}
|
|
2282
3032
|
assertUnacknowledged() {
|
|
2283
|
-
if (this.replied || this.deferred)
|
|
3033
|
+
if (this.replied || this.deferred || this.#acknowledging)
|
|
2284
3034
|
throw new Error("Interaction has already been acknowledged.");
|
|
2285
3035
|
}
|
|
3036
|
+
async acknowledge(response, state) {
|
|
3037
|
+
this.assertUnacknowledged();
|
|
3038
|
+
this.#acknowledging = true;
|
|
3039
|
+
try {
|
|
3040
|
+
const result = await this.postResponse(response);
|
|
3041
|
+
this[state] = true;
|
|
3042
|
+
return result;
|
|
3043
|
+
} finally {
|
|
3044
|
+
this.#acknowledging = false;
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
get user() {
|
|
3048
|
+
const raw = this.data.member?.user ?? this.data.user;
|
|
3049
|
+
return raw ? new User(raw) : null;
|
|
3050
|
+
}
|
|
3051
|
+
get member() {
|
|
3052
|
+
const raw = this.data.member;
|
|
3053
|
+
if (!raw || !this.guildId)
|
|
3054
|
+
return null;
|
|
3055
|
+
return new GuildMember({
|
|
3056
|
+
...raw,
|
|
3057
|
+
guild_id: this.guildId
|
|
3058
|
+
}, this.#client.resourceContext);
|
|
3059
|
+
}
|
|
3060
|
+
get createdTimestamp() {
|
|
3061
|
+
return Number((BigInt(this.id) >> 22n) + DISCORD_EPOCH);
|
|
3062
|
+
}
|
|
3063
|
+
get expiresAt() {
|
|
3064
|
+
return new Date(this.createdTimestamp + TOKEN_LIFETIME_MS);
|
|
3065
|
+
}
|
|
3066
|
+
get isExpired() {
|
|
3067
|
+
return Date.now() >= this.createdTimestamp + TOKEN_LIFETIME_MS;
|
|
3068
|
+
}
|
|
3069
|
+
#webhookMessage(method, messageId, data) {
|
|
3070
|
+
if (!this.#client.interactionWebhookMessage)
|
|
3071
|
+
return Promise.reject(new Error("This interaction client does not support webhook message access."));
|
|
3072
|
+
return this.#client.interactionWebhookMessage(method, this.applicationId, this.token, messageId, data);
|
|
3073
|
+
}
|
|
3074
|
+
fetchReply() {
|
|
3075
|
+
this.assertAcknowledged();
|
|
3076
|
+
return this.#webhookMessage("GET", "@original");
|
|
3077
|
+
}
|
|
3078
|
+
editFollowUp(messageId, options) {
|
|
3079
|
+
return this.#webhookMessage("PATCH", messageId, toMessageData(options));
|
|
3080
|
+
}
|
|
3081
|
+
async deleteFollowUp(messageId) {
|
|
3082
|
+
await this.#webhookMessage("DELETE", messageId);
|
|
3083
|
+
}
|
|
2286
3084
|
assertAcknowledged() {
|
|
2287
3085
|
if (!this.replied && !this.deferred)
|
|
2288
3086
|
throw new Error("Interaction has not been acknowledged.");
|
|
@@ -2291,41 +3089,29 @@ class Interaction {
|
|
|
2291
3089
|
return this.#client.postInteractionResponse(this.id, this.token, response);
|
|
2292
3090
|
}
|
|
2293
3091
|
async reply(options) {
|
|
2294
|
-
this.
|
|
2295
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2296
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.message(payload));
|
|
2297
|
-
this.replied = true;
|
|
2298
|
-
return result;
|
|
3092
|
+
return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
|
|
2299
3093
|
}
|
|
2300
|
-
async deferReply(
|
|
2301
|
-
|
|
2302
|
-
await this
|
|
2303
|
-
this.deferred = true;
|
|
3094
|
+
async deferReply(options = false) {
|
|
3095
|
+
const ephemeral = typeof options === "boolean" ? options : options.ephemeral === true;
|
|
3096
|
+
await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
|
|
2304
3097
|
}
|
|
2305
3098
|
editReply(options) {
|
|
2306
3099
|
this.assertAcknowledged();
|
|
2307
|
-
return this.#client.editInteractionReply(this.token, options);
|
|
3100
|
+
return this.#client.editInteractionReply(this.token, toMessageData(options));
|
|
2308
3101
|
}
|
|
2309
3102
|
deleteReply() {
|
|
2310
3103
|
this.assertAcknowledged();
|
|
2311
3104
|
return this.#client.deleteInteractionReply(this.token);
|
|
2312
3105
|
}
|
|
2313
3106
|
followUp(options) {
|
|
2314
|
-
|
|
2315
|
-
return this.#client.followUpInteraction(this.token, payload);
|
|
3107
|
+
return this.#client.followUpInteraction(this.token, toMessageData(options));
|
|
2316
3108
|
}
|
|
2317
3109
|
async update(options) {
|
|
2318
|
-
this.
|
|
2319
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2320
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
|
|
2321
|
-
this.replied = true;
|
|
2322
|
-
return result;
|
|
3110
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2323
3111
|
}
|
|
2324
3112
|
async showModal(modal) {
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
this.replied = true;
|
|
2328
|
-
return result;
|
|
3113
|
+
const data = "toJSON" in modal && typeof modal.toJSON === "function" ? modal.toJSON() : modal;
|
|
3114
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, data), "replied");
|
|
2329
3115
|
}
|
|
2330
3116
|
}
|
|
2331
3117
|
|
|
@@ -2346,6 +3132,9 @@ class ComponentInteraction extends Interaction {
|
|
|
2346
3132
|
get customId() {
|
|
2347
3133
|
return this.data?.data?.custom_id ?? "";
|
|
2348
3134
|
}
|
|
3135
|
+
get messageId() {
|
|
3136
|
+
return this.data?.message?.id;
|
|
3137
|
+
}
|
|
2349
3138
|
get componentType() {
|
|
2350
3139
|
return this.data?.data?.component_type ?? 0;
|
|
2351
3140
|
}
|
|
@@ -2353,16 +3142,10 @@ class ComponentInteraction extends Interaction {
|
|
|
2353
3142
|
return this.data?.data?.values ?? [];
|
|
2354
3143
|
}
|
|
2355
3144
|
async deferUpdate() {
|
|
2356
|
-
this.
|
|
2357
|
-
await this.postResponse(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate));
|
|
2358
|
-
this.deferred = true;
|
|
3145
|
+
await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
|
|
2359
3146
|
}
|
|
2360
3147
|
async update(options) {
|
|
2361
|
-
this.
|
|
2362
|
-
const payload = typeof options === "string" ? { content: options } : options;
|
|
2363
|
-
const result = await this.postResponse(new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
|
|
2364
|
-
this.replied = true;
|
|
2365
|
-
return result;
|
|
3148
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2366
3149
|
}
|
|
2367
3150
|
}
|
|
2368
3151
|
|
|
@@ -2405,8 +3188,7 @@ class AutocompleteInteraction extends Interaction {
|
|
|
2405
3188
|
if (!Array.isArray(choices))
|
|
2406
3189
|
throw new TypeError("Autocomplete choices must be an array.");
|
|
2407
3190
|
const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
|
|
2408
|
-
await this.
|
|
2409
|
-
this.replied = true;
|
|
3191
|
+
await this.acknowledge(response, "replied");
|
|
2410
3192
|
}
|
|
2411
3193
|
}
|
|
2412
3194
|
function findFocused(options) {
|
|
@@ -2437,6 +3219,7 @@ function createInteraction(client, data) {
|
|
|
2437
3219
|
}
|
|
2438
3220
|
|
|
2439
3221
|
// packages/structures/src/index.ts
|
|
3222
|
+
var COMPONENT_COLLECTOR_DEFAULT_TIME = 15 * 60000;
|
|
2440
3223
|
var NON_SYSTEM_MESSAGE_TYPES = new Set([0, 19, 20, 23]);
|
|
2441
3224
|
|
|
2442
3225
|
class Message extends BaseStructure {
|
|
@@ -2457,6 +3240,7 @@ class Message extends BaseStructure {
|
|
|
2457
3240
|
reference;
|
|
2458
3241
|
components;
|
|
2459
3242
|
referencedMessage;
|
|
3243
|
+
member;
|
|
2460
3244
|
#context;
|
|
2461
3245
|
constructor(data, context) {
|
|
2462
3246
|
super(data.id);
|
|
@@ -2479,6 +3263,11 @@ class Message extends BaseStructure {
|
|
|
2479
3263
|
this.reference = data.message_reference;
|
|
2480
3264
|
this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
|
|
2481
3265
|
this.#context = context;
|
|
3266
|
+
this.member = data.member && data.guild_id ? new GuildMember({
|
|
3267
|
+
...data.member,
|
|
3268
|
+
user: data.member.user ?? data.author,
|
|
3269
|
+
guild_id: data.guild_id
|
|
3270
|
+
}, context) : null;
|
|
2482
3271
|
this.channel = new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context);
|
|
2483
3272
|
}
|
|
2484
3273
|
get embedsSuppressed() {
|
|
@@ -2519,6 +3308,20 @@ class Message extends BaseStructure {
|
|
|
2519
3308
|
throw new Error("This message is not attached to a client.");
|
|
2520
3309
|
return this.#context.crosspostMessage(this.channelId, this.id);
|
|
2521
3310
|
}
|
|
3311
|
+
createComponentCollector(options = {}) {
|
|
3312
|
+
const collect = this.#context?.collectInteractions;
|
|
3313
|
+
if (!collect)
|
|
3314
|
+
throw new Error("This message is not attached to a client.");
|
|
3315
|
+
const { componentType, filter, ...rest } = options;
|
|
3316
|
+
return collect({
|
|
3317
|
+
...rest,
|
|
3318
|
+
time: rest.time ?? (rest.idle ? undefined : COMPONENT_COLLECTOR_DEFAULT_TIME),
|
|
3319
|
+
filter: async (interaction) => interaction.isMessageComponent() && interaction.messageId === this.id && (componentType === undefined || interaction.componentType === componentType) && (filter ? await filter(interaction) : true)
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
awaitComponent(options = {}) {
|
|
3323
|
+
return this.createComponentCollector({ ...options, max: 1 }).next();
|
|
3324
|
+
}
|
|
2522
3325
|
react(emoji) {
|
|
2523
3326
|
if (!this.#context?.addReaction)
|
|
2524
3327
|
throw new Error("This message is not attached to a client.");
|
|
@@ -2592,23 +3395,43 @@ class Message extends BaseStructure {
|
|
|
2592
3395
|
}
|
|
2593
3396
|
|
|
2594
3397
|
// packages/managers/src/message.ts
|
|
3398
|
+
function toRequest(options) {
|
|
3399
|
+
const { files, ...body } = options;
|
|
3400
|
+
if (!files?.length)
|
|
3401
|
+
return body;
|
|
3402
|
+
return {
|
|
3403
|
+
body,
|
|
3404
|
+
files: files.map((file) => ({
|
|
3405
|
+
name: file.name,
|
|
3406
|
+
data: typeof file.data === "string" ? new TextEncoder().encode(file.data) : file.data,
|
|
3407
|
+
contentType: file.contentType
|
|
3408
|
+
}))
|
|
3409
|
+
};
|
|
3410
|
+
}
|
|
3411
|
+
|
|
2595
3412
|
class MessageManager {
|
|
2596
|
-
cache
|
|
3413
|
+
cache;
|
|
3414
|
+
#caching;
|
|
2597
3415
|
#rest;
|
|
2598
3416
|
#context;
|
|
2599
3417
|
#channelId;
|
|
2600
|
-
constructor(rest, context, channelId) {
|
|
3418
|
+
constructor(rest, context, channelId, cache) {
|
|
2601
3419
|
if (!channelId)
|
|
2602
3420
|
throw new TypeError("Channel ID is required.");
|
|
2603
3421
|
this.#rest = rest;
|
|
2604
3422
|
this.#context = context;
|
|
2605
3423
|
this.#channelId = channelId;
|
|
3424
|
+
this.#caching = cache !== undefined;
|
|
3425
|
+
this.cache = new Collection(null, {
|
|
3426
|
+
ttl: cache?.ttl,
|
|
3427
|
+
maxSize: cache ? cache.maxSize ?? 100 : undefined
|
|
3428
|
+
});
|
|
2606
3429
|
}
|
|
2607
3430
|
async resolve(messageId) {
|
|
2608
3431
|
return this.cache.get(messageId) ?? this.fetch(messageId);
|
|
2609
3432
|
}
|
|
2610
3433
|
async send(options) {
|
|
2611
|
-
const data = await this.#rest.post(Routes.channelMessages(this.#channelId), options);
|
|
3434
|
+
const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options));
|
|
2612
3435
|
return this.upsert(data);
|
|
2613
3436
|
}
|
|
2614
3437
|
async fetch(messageId) {
|
|
@@ -2619,13 +3442,14 @@ class MessageManager {
|
|
|
2619
3442
|
return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
|
|
2620
3443
|
}
|
|
2621
3444
|
upsert(data) {
|
|
2622
|
-
const existing = this.cache.
|
|
3445
|
+
const existing = this.cache.peek(data.id);
|
|
2623
3446
|
const message = new Message(data, this.#context);
|
|
2624
3447
|
if (existing) {
|
|
2625
3448
|
Object.assign(existing, message);
|
|
2626
3449
|
return existing;
|
|
2627
3450
|
}
|
|
2628
|
-
this
|
|
3451
|
+
if (this.#caching)
|
|
3452
|
+
this.cache.set(message.id, message);
|
|
2629
3453
|
return message;
|
|
2630
3454
|
}
|
|
2631
3455
|
delete(messageId) {
|
|
@@ -2679,8 +3503,301 @@ class UserManager extends ResourceManager {
|
|
|
2679
3503
|
});
|
|
2680
3504
|
}
|
|
2681
3505
|
}
|
|
3506
|
+
// packages/managers/src/emoji.ts
|
|
3507
|
+
class EmojiManager extends Manager {
|
|
3508
|
+
#rest;
|
|
3509
|
+
#guildId;
|
|
3510
|
+
constructor(rest, guildId) {
|
|
3511
|
+
super();
|
|
3512
|
+
this.#rest = rest;
|
|
3513
|
+
this.#guildId = guildId;
|
|
3514
|
+
}
|
|
3515
|
+
fetch(emojiId) {
|
|
3516
|
+
return this.fetchOnce(emojiId, async () => new Emoji(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId))), (emoji) => this.#merge(emojiId, emoji));
|
|
3517
|
+
}
|
|
3518
|
+
async fetchAll() {
|
|
3519
|
+
const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
|
|
3520
|
+
return data.map((item) => this.upsert(item));
|
|
3521
|
+
}
|
|
3522
|
+
async create(options) {
|
|
3523
|
+
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
|
|
3524
|
+
}
|
|
3525
|
+
async edit(emojiId, options) {
|
|
3526
|
+
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
|
|
3527
|
+
}
|
|
3528
|
+
async deleteEmoji(emojiId) {
|
|
3529
|
+
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
|
|
3530
|
+
this.delete(emojiId);
|
|
3531
|
+
}
|
|
3532
|
+
upsert(data) {
|
|
3533
|
+
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
3534
|
+
return this.#merge(key, new Emoji(data));
|
|
3535
|
+
}
|
|
3536
|
+
#merge(key, emoji) {
|
|
3537
|
+
const existing = this.get(key);
|
|
3538
|
+
if (existing) {
|
|
3539
|
+
Object.assign(existing, emoji);
|
|
3540
|
+
return existing;
|
|
3541
|
+
}
|
|
3542
|
+
this.set(key, emoji);
|
|
3543
|
+
return emoji;
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
// packages/managers/src/advanced.ts
|
|
3548
|
+
function withQuery(path, query) {
|
|
3549
|
+
const params = new URLSearchParams;
|
|
3550
|
+
for (const [key, value] of Object.entries(query))
|
|
3551
|
+
if (value !== undefined)
|
|
3552
|
+
params.set(key, String(value));
|
|
3553
|
+
const suffix = params.toString();
|
|
3554
|
+
return suffix ? `${path}?${suffix}` : path;
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
class GuildStickerManager extends Manager {
|
|
3558
|
+
#rest;
|
|
3559
|
+
guildId;
|
|
3560
|
+
constructor(rest, guildId) {
|
|
3561
|
+
super();
|
|
3562
|
+
this.#rest = rest;
|
|
3563
|
+
this.guildId = guildId;
|
|
3564
|
+
}
|
|
3565
|
+
#store(sticker) {
|
|
3566
|
+
this.set(sticker.id, sticker);
|
|
3567
|
+
return sticker;
|
|
3568
|
+
}
|
|
3569
|
+
async fetchAll() {
|
|
3570
|
+
const stickers = await this.#rest.get(Routes.guildSticker(this.guildId));
|
|
3571
|
+
this.clear();
|
|
3572
|
+
return stickers.map((sticker) => this.#store(sticker));
|
|
3573
|
+
}
|
|
3574
|
+
async fetch(stickerId) {
|
|
3575
|
+
return this.#store(await this.#rest.get(Routes.guildSticker(this.guildId, stickerId)));
|
|
3576
|
+
}
|
|
3577
|
+
async create(options) {
|
|
3578
|
+
const form = new FormData;
|
|
3579
|
+
form.set("name", options.name);
|
|
3580
|
+
form.set("description", options.description);
|
|
3581
|
+
form.set("tags", options.tags);
|
|
3582
|
+
form.set("file", options.file);
|
|
3583
|
+
return this.#store(await this.#rest.post(Routes.guildSticker(this.guildId), form, { reason: options.reason }));
|
|
3584
|
+
}
|
|
3585
|
+
async edit(stickerId, options) {
|
|
3586
|
+
const { reason, ...body } = options;
|
|
3587
|
+
return this.#store(await this.#rest.patch(Routes.guildSticker(this.guildId, stickerId), body, { reason }));
|
|
3588
|
+
}
|
|
3589
|
+
async remove(stickerId, reason) {
|
|
3590
|
+
await this.#rest.delete(Routes.guildSticker(this.guildId, stickerId), {
|
|
3591
|
+
reason
|
|
3592
|
+
});
|
|
3593
|
+
this.delete(stickerId);
|
|
3594
|
+
}
|
|
3595
|
+
sync(stickers) {
|
|
3596
|
+
this.clear();
|
|
3597
|
+
for (const sticker of stickers)
|
|
3598
|
+
this.#store(sticker);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
class GuildSoundboardManager extends Manager {
|
|
3603
|
+
#rest;
|
|
3604
|
+
guildId;
|
|
3605
|
+
constructor(rest, guildId) {
|
|
3606
|
+
super();
|
|
3607
|
+
this.#rest = rest;
|
|
3608
|
+
this.guildId = guildId;
|
|
3609
|
+
}
|
|
3610
|
+
#store(sound) {
|
|
3611
|
+
this.set(sound.sound_id, sound);
|
|
3612
|
+
return sound;
|
|
3613
|
+
}
|
|
3614
|
+
async fetchAll() {
|
|
3615
|
+
const { items } = await this.#rest.get(Routes.guildSoundboardSound(this.guildId));
|
|
3616
|
+
this.clear();
|
|
3617
|
+
return items.map((sound) => this.#store(sound));
|
|
3618
|
+
}
|
|
3619
|
+
async fetch(soundId) {
|
|
3620
|
+
return this.#store(await this.#rest.get(Routes.guildSoundboardSound(this.guildId, soundId)));
|
|
3621
|
+
}
|
|
3622
|
+
async create(options) {
|
|
3623
|
+
if (options.volume !== undefined && (options.volume < 0 || options.volume > 1))
|
|
3624
|
+
throw new RangeError("Soundboard volume must be between 0 and 1.");
|
|
3625
|
+
return this.#store(await this.#rest.post(Routes.guildSoundboardSound(this.guildId), {
|
|
3626
|
+
name: options.name,
|
|
3627
|
+
sound: options.sound,
|
|
3628
|
+
volume: options.volume,
|
|
3629
|
+
emoji_id: options.emojiId,
|
|
3630
|
+
emoji_name: options.emojiName
|
|
3631
|
+
}, { reason: options.reason }));
|
|
3632
|
+
}
|
|
3633
|
+
async edit(soundId, options) {
|
|
3634
|
+
return this.#store(await this.#rest.patch(Routes.guildSoundboardSound(this.guildId, soundId), {
|
|
3635
|
+
name: options.name,
|
|
3636
|
+
volume: options.volume,
|
|
3637
|
+
emoji_id: options.emojiId,
|
|
3638
|
+
emoji_name: options.emojiName
|
|
3639
|
+
}, { reason: options.reason }));
|
|
3640
|
+
}
|
|
3641
|
+
async remove(soundId, reason) {
|
|
3642
|
+
await this.#rest.delete(Routes.guildSoundboardSound(this.guildId, soundId), { reason });
|
|
3643
|
+
this.delete(soundId);
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
class MonetizationManager extends Manager {
|
|
3648
|
+
#rest;
|
|
3649
|
+
applicationId;
|
|
3650
|
+
constructor(rest, applicationId) {
|
|
3651
|
+
super();
|
|
3652
|
+
this.#rest = rest;
|
|
3653
|
+
this.applicationId = applicationId;
|
|
3654
|
+
}
|
|
3655
|
+
fetchSkus() {
|
|
3656
|
+
return this.#rest.get(Routes.applicationSkus(this.applicationId));
|
|
3657
|
+
}
|
|
3658
|
+
async fetchEntitlements(query = {}) {
|
|
3659
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 100))
|
|
3660
|
+
throw new RangeError("Entitlement limit must be 1-100.");
|
|
3661
|
+
const entitlements = await this.#rest.get(withQuery(Routes.applicationEntitlement(this.applicationId), {
|
|
3662
|
+
user_id: query.userId,
|
|
3663
|
+
sku_ids: query.skuIds?.join(","),
|
|
3664
|
+
guild_id: query.guildId,
|
|
3665
|
+
before: query.before,
|
|
3666
|
+
after: query.after,
|
|
3667
|
+
limit: query.limit,
|
|
3668
|
+
exclude_ended: query.excludeEnded,
|
|
3669
|
+
exclude_deleted: query.excludeDeleted
|
|
3670
|
+
}));
|
|
3671
|
+
for (const entitlement of entitlements)
|
|
3672
|
+
this.set(entitlement.id, entitlement);
|
|
3673
|
+
return entitlements;
|
|
3674
|
+
}
|
|
3675
|
+
async fetch(entitlementId) {
|
|
3676
|
+
const entitlement = await this.#rest.get(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
3677
|
+
this.set(entitlement.id, entitlement);
|
|
3678
|
+
return entitlement;
|
|
3679
|
+
}
|
|
3680
|
+
async consume(entitlementId) {
|
|
3681
|
+
await this.#rest.post(Routes.consumeEntitlement(this.applicationId, entitlementId));
|
|
3682
|
+
const cached = this.get(entitlementId);
|
|
3683
|
+
if (cached)
|
|
3684
|
+
cached.consumed = true;
|
|
3685
|
+
}
|
|
3686
|
+
async createTestEntitlement(options) {
|
|
3687
|
+
const entitlement = await this.#rest.post(Routes.applicationEntitlement(this.applicationId), {
|
|
3688
|
+
sku_id: options.skuId,
|
|
3689
|
+
owner_id: options.ownerId,
|
|
3690
|
+
owner_type: options.ownerType
|
|
3691
|
+
});
|
|
3692
|
+
this.set(entitlement.id, entitlement);
|
|
3693
|
+
return entitlement;
|
|
3694
|
+
}
|
|
3695
|
+
async deleteTestEntitlement(entitlementId) {
|
|
3696
|
+
await this.#rest.delete(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
3697
|
+
this.delete(entitlementId);
|
|
3698
|
+
}
|
|
3699
|
+
fetchSubscriptions(skuId, query = {}) {
|
|
3700
|
+
return this.#rest.get(withQuery(Routes.skuSubscription(skuId), {
|
|
3701
|
+
user_id: query.userId,
|
|
3702
|
+
before: query.before,
|
|
3703
|
+
after: query.after,
|
|
3704
|
+
limit: query.limit
|
|
3705
|
+
}));
|
|
3706
|
+
}
|
|
3707
|
+
fetchSubscription(skuId, subscriptionId) {
|
|
3708
|
+
return this.#rest.get(Routes.skuSubscription(skuId, subscriptionId));
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
|
|
3712
|
+
// packages/managers/src/member.ts
|
|
3713
|
+
class GuildMemberManager extends ResourceManager {
|
|
3714
|
+
#rest;
|
|
3715
|
+
#context;
|
|
3716
|
+
guildId;
|
|
3717
|
+
constructor(guildId, rest, context = () => {
|
|
3718
|
+
return;
|
|
3719
|
+
}) {
|
|
3720
|
+
super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId }, context())), (member) => member.user.id);
|
|
3721
|
+
this.guildId = guildId;
|
|
3722
|
+
this.#rest = rest;
|
|
3723
|
+
this.#context = context;
|
|
3724
|
+
}
|
|
3725
|
+
async kick(userId, reason) {
|
|
3726
|
+
await this.#rest.delete(Routes.guildMember(this.guildId, userId), {
|
|
3727
|
+
reason
|
|
3728
|
+
});
|
|
3729
|
+
this.delete(userId);
|
|
3730
|
+
}
|
|
3731
|
+
async ban(userId, options = {}) {
|
|
3732
|
+
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
3733
|
+
this.delete(userId);
|
|
3734
|
+
}
|
|
3735
|
+
async unban(userId) {
|
|
3736
|
+
await this.#rest.delete(Routes.guildBan(this.guildId, userId));
|
|
3737
|
+
}
|
|
3738
|
+
async edit(userId, options, reason) {
|
|
3739
|
+
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options, { reason });
|
|
3740
|
+
const member = new GuildMember({ ...data, guild_id: this.guildId }, this.#context());
|
|
3741
|
+
this.set(member.user.id, member);
|
|
3742
|
+
return member;
|
|
3743
|
+
}
|
|
3744
|
+
async addRole(userId, roleId, reason) {
|
|
3745
|
+
await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId), undefined, { reason });
|
|
3746
|
+
}
|
|
3747
|
+
async removeRole(userId, roleId, reason) {
|
|
3748
|
+
await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId), { reason });
|
|
3749
|
+
}
|
|
3750
|
+
async timeout(userId, milliseconds, reason) {
|
|
3751
|
+
const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
|
|
3752
|
+
return this.edit(userId, { communication_disabled_until: timeoutDate }, reason);
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
|
|
3756
|
+
// packages/managers/src/role.ts
|
|
3757
|
+
class RoleManager extends ResourceManager {
|
|
3758
|
+
#rest;
|
|
3759
|
+
guildId;
|
|
3760
|
+
constructor(guildId, rest) {
|
|
3761
|
+
super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
|
|
3762
|
+
this.guildId = guildId;
|
|
3763
|
+
this.#rest = rest;
|
|
3764
|
+
}
|
|
3765
|
+
async fetchAll() {
|
|
3766
|
+
const data = await this.#rest.get(Routes.guildRoles(this.guildId));
|
|
3767
|
+
return data.map((item) => {
|
|
3768
|
+
const role = new Role(item);
|
|
3769
|
+
this.set(role.id, role);
|
|
3770
|
+
return role;
|
|
3771
|
+
});
|
|
3772
|
+
}
|
|
3773
|
+
async create(options) {
|
|
3774
|
+
const { reason, ...payload } = options;
|
|
3775
|
+
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
3776
|
+
...payload,
|
|
3777
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3778
|
+
});
|
|
3779
|
+
const role = new Role(data);
|
|
3780
|
+
this.set(role.id, role);
|
|
3781
|
+
return role;
|
|
3782
|
+
}
|
|
3783
|
+
async edit(roleId, options) {
|
|
3784
|
+
const { reason, ...payload } = options;
|
|
3785
|
+
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
3786
|
+
...payload,
|
|
3787
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3788
|
+
});
|
|
3789
|
+
const role = new Role(data);
|
|
3790
|
+
this.set(role.id, role);
|
|
3791
|
+
return role;
|
|
3792
|
+
}
|
|
3793
|
+
async deleteRole(roleId) {
|
|
3794
|
+
await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
|
|
3795
|
+
this.delete(roleId);
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
|
|
2682
3799
|
// packages/managers/src/guild-resources.ts
|
|
2683
|
-
function
|
|
3800
|
+
function withQuery2(path, params) {
|
|
2684
3801
|
const query = new URLSearchParams;
|
|
2685
3802
|
for (const [key, value] of Object.entries(params))
|
|
2686
3803
|
if (value !== undefined)
|
|
@@ -2704,7 +3821,7 @@ class GuildBanManager extends Manager {
|
|
|
2704
3821
|
}
|
|
2705
3822
|
async fetchAll(options = {}) {
|
|
2706
3823
|
const limit = options.limit === undefined ? undefined : Math.min(1000, Math.max(1, options.limit));
|
|
2707
|
-
const bans = await this.#rest.get(
|
|
3824
|
+
const bans = await this.#rest.get(withQuery2(Routes.guildBans(this.guildId), {
|
|
2708
3825
|
limit,
|
|
2709
3826
|
before: options.before,
|
|
2710
3827
|
after: options.after
|
|
@@ -2737,12 +3854,12 @@ class GuildScheduledEventManager extends Manager {
|
|
|
2737
3854
|
return event;
|
|
2738
3855
|
}
|
|
2739
3856
|
async fetch(eventId, options = {}) {
|
|
2740
|
-
return this.#store(await this.#rest.get(
|
|
3857
|
+
return this.#store(await this.#rest.get(withQuery2(Routes.guildScheduledEvent(this.guildId, eventId), {
|
|
2741
3858
|
with_user_count: options.withUserCount
|
|
2742
3859
|
})));
|
|
2743
3860
|
}
|
|
2744
3861
|
async fetchAll(options = {}) {
|
|
2745
|
-
const events = await this.#rest.get(
|
|
3862
|
+
const events = await this.#rest.get(withQuery2(Routes.guildScheduledEvents(this.guildId), {
|
|
2746
3863
|
with_user_count: options.withUserCount
|
|
2747
3864
|
}));
|
|
2748
3865
|
return events.map((event) => this.#store(event));
|
|
@@ -2759,7 +3876,7 @@ class GuildScheduledEventManager extends Manager {
|
|
|
2759
3876
|
}
|
|
2760
3877
|
async fetchSubscribers(eventId, options = {}) {
|
|
2761
3878
|
const limit = options.limit === undefined ? undefined : Math.min(100, Math.max(1, options.limit));
|
|
2762
|
-
return this.#rest.get(
|
|
3879
|
+
return this.#rest.get(withQuery2(Routes.guildScheduledEventUsers(this.guildId, eventId), {
|
|
2763
3880
|
limit,
|
|
2764
3881
|
with_member: options.withMember,
|
|
2765
3882
|
before: options.before,
|
|
@@ -2803,10 +3920,25 @@ class StageInstanceManager extends Manager {
|
|
|
2803
3920
|
|
|
2804
3921
|
class PermissionOverwriteManager {
|
|
2805
3922
|
#rest;
|
|
3923
|
+
#current;
|
|
2806
3924
|
channelId;
|
|
2807
|
-
constructor(rest, channelId) {
|
|
3925
|
+
constructor(rest, channelId, current = () => {
|
|
3926
|
+
return;
|
|
3927
|
+
}) {
|
|
2808
3928
|
this.#rest = rest;
|
|
2809
3929
|
this.channelId = channelId;
|
|
3930
|
+
this.#current = current;
|
|
3931
|
+
}
|
|
3932
|
+
async update(overwriteId, changes, options = {}) {
|
|
3933
|
+
const overwrites = this.#current() ?? (await this.#rest.get(Routes.channel(this.channelId))).permission_overwrites ?? [];
|
|
3934
|
+
const existing = overwrites.find((entry) => entry.id === overwriteId);
|
|
3935
|
+
const type = existing?.type ?? options.type;
|
|
3936
|
+
if (type !== 0 && type !== 1)
|
|
3937
|
+
throw new TypeError("A new permission overwrite needs a type: 0 for a role, 1 for a member.");
|
|
3938
|
+
const touched = (changes.allow ?? 0n) | (changes.deny ?? 0n) | (changes.inherit ?? 0n);
|
|
3939
|
+
const allow = BigInt(existing?.allow ?? 0) & ~touched | (changes.allow ?? 0n);
|
|
3940
|
+
const deny = BigInt(existing?.deny ?? 0) & ~touched | (changes.deny ?? 0n);
|
|
3941
|
+
await this.edit(overwriteId, { type, allow, deny }, options.reason);
|
|
2810
3942
|
}
|
|
2811
3943
|
async edit(overwriteId, options, reason) {
|
|
2812
3944
|
await this.#rest.put(Routes.channelPermission(this.channelId, overwriteId), {
|
|
@@ -2821,7 +3953,7 @@ class PermissionOverwriteManager {
|
|
|
2821
3953
|
}
|
|
2822
3954
|
|
|
2823
3955
|
// packages/managers/src/guild.ts
|
|
2824
|
-
function
|
|
3956
|
+
function withQuery3(path, params) {
|
|
2825
3957
|
const suffix = params.toString();
|
|
2826
3958
|
return suffix ? `${path}?${suffix}` : path;
|
|
2827
3959
|
}
|
|
@@ -2830,6 +3962,24 @@ class GuildManager extends ResourceManager {
|
|
|
2830
3962
|
#rest;
|
|
2831
3963
|
#bans = new Map;
|
|
2832
3964
|
#scheduledEvents = new Map;
|
|
3965
|
+
#members = new Map;
|
|
3966
|
+
#roles = new Map;
|
|
3967
|
+
#emojis = new Map;
|
|
3968
|
+
#stickers = new Map;
|
|
3969
|
+
#soundboard = new Map;
|
|
3970
|
+
#voiceStates = new Map;
|
|
3971
|
+
#autoModerationRules = new Map;
|
|
3972
|
+
#invites = new Map;
|
|
3973
|
+
#context;
|
|
3974
|
+
attachContext(context) {
|
|
3975
|
+
this.#context = context;
|
|
3976
|
+
}
|
|
3977
|
+
#perGuild(map, guildId, create) {
|
|
3978
|
+
let manager = map.get(guildId);
|
|
3979
|
+
if (!manager)
|
|
3980
|
+
map.set(guildId, manager = create());
|
|
3981
|
+
return manager;
|
|
3982
|
+
}
|
|
2833
3983
|
constructor(rest) {
|
|
2834
3984
|
super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
|
|
2835
3985
|
this.#rest = rest;
|
|
@@ -2846,6 +3996,68 @@ class GuildManager extends ResourceManager {
|
|
|
2846
3996
|
this.#scheduledEvents.set(guildId, manager = new GuildScheduledEventManager(this.#rest, guildId));
|
|
2847
3997
|
return manager;
|
|
2848
3998
|
}
|
|
3999
|
+
members(guildId) {
|
|
4000
|
+
let manager = this.#members.get(guildId);
|
|
4001
|
+
if (!manager)
|
|
4002
|
+
this.#members.set(guildId, manager = new GuildMemberManager(guildId, this.#rest, () => this.#context));
|
|
4003
|
+
return manager;
|
|
4004
|
+
}
|
|
4005
|
+
roles(guildId) {
|
|
4006
|
+
let manager = this.#roles.get(guildId);
|
|
4007
|
+
if (!manager)
|
|
4008
|
+
this.#roles.set(guildId, manager = new RoleManager(guildId, this.#rest));
|
|
4009
|
+
return manager;
|
|
4010
|
+
}
|
|
4011
|
+
emojis(guildId) {
|
|
4012
|
+
let manager = this.#emojis.get(guildId);
|
|
4013
|
+
if (!manager)
|
|
4014
|
+
this.#emojis.set(guildId, manager = new EmojiManager(this.#rest, guildId));
|
|
4015
|
+
return manager;
|
|
4016
|
+
}
|
|
4017
|
+
stickers(guildId) {
|
|
4018
|
+
let manager = this.#stickers.get(guildId);
|
|
4019
|
+
if (!manager)
|
|
4020
|
+
this.#stickers.set(guildId, manager = new GuildStickerManager(this.#rest, guildId));
|
|
4021
|
+
return manager;
|
|
4022
|
+
}
|
|
4023
|
+
soundboard(guildId) {
|
|
4024
|
+
let manager = this.#soundboard.get(guildId);
|
|
4025
|
+
if (!manager)
|
|
4026
|
+
this.#soundboard.set(guildId, manager = new GuildSoundboardManager(this.#rest, guildId));
|
|
4027
|
+
return manager;
|
|
4028
|
+
}
|
|
4029
|
+
voiceStates(guildId) {
|
|
4030
|
+
return this.#perGuild(this.#voiceStates, guildId, () => new Manager);
|
|
4031
|
+
}
|
|
4032
|
+
autoModerationRules(guildId) {
|
|
4033
|
+
return this.#perGuild(this.#autoModerationRules, guildId, () => new Manager);
|
|
4034
|
+
}
|
|
4035
|
+
invites(guildId) {
|
|
4036
|
+
return this.#perGuild(this.#invites, guildId, () => new Manager);
|
|
4037
|
+
}
|
|
4038
|
+
patch(data) {
|
|
4039
|
+
const guild = new Guild(data);
|
|
4040
|
+
const existing = this.get(guild.id);
|
|
4041
|
+
if (!existing)
|
|
4042
|
+
return this.upsert(guild);
|
|
4043
|
+
for (const [key, value] of Object.entries(guild))
|
|
4044
|
+
if (value !== undefined)
|
|
4045
|
+
existing[key] = value;
|
|
4046
|
+
return existing;
|
|
4047
|
+
}
|
|
4048
|
+
delete(id) {
|
|
4049
|
+
this.#bans.delete(id);
|
|
4050
|
+
this.#scheduledEvents.delete(id);
|
|
4051
|
+
this.#members.delete(id);
|
|
4052
|
+
this.#roles.delete(id);
|
|
4053
|
+
this.#emojis.delete(id);
|
|
4054
|
+
this.#stickers.delete(id);
|
|
4055
|
+
this.#soundboard.delete(id);
|
|
4056
|
+
this.#voiceStates.delete(id);
|
|
4057
|
+
this.#autoModerationRules.delete(id);
|
|
4058
|
+
this.#invites.delete(id);
|
|
4059
|
+
return super.delete(id);
|
|
4060
|
+
}
|
|
2849
4061
|
async create(options) {
|
|
2850
4062
|
const data = await this.#rest.post("/guilds", options);
|
|
2851
4063
|
return this.upsert(new Guild(data));
|
|
@@ -2881,7 +4093,7 @@ class GuildManager extends ResourceManager {
|
|
|
2881
4093
|
params.set("after", options.after);
|
|
2882
4094
|
if (options.limit !== undefined)
|
|
2883
4095
|
params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
|
|
2884
|
-
return this.#rest.get(
|
|
4096
|
+
return this.#rest.get(withQuery3(Routes.guildAuditLog(guildId), params));
|
|
2885
4097
|
}
|
|
2886
4098
|
async fetchMembers(guildId, options = {}) {
|
|
2887
4099
|
const params = new URLSearchParams;
|
|
@@ -2889,7 +4101,7 @@ class GuildManager extends ResourceManager {
|
|
|
2889
4101
|
params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
|
|
2890
4102
|
if (options.after)
|
|
2891
4103
|
params.set("after", options.after);
|
|
2892
|
-
return this.#rest.get(
|
|
4104
|
+
return this.#rest.get(withQuery3(Routes.guildMembers(guildId), params));
|
|
2893
4105
|
}
|
|
2894
4106
|
async fetchAutoModerationRules(guildId) {
|
|
2895
4107
|
const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
|
|
@@ -2952,13 +4164,20 @@ class ApplicationCommandManager {
|
|
|
2952
4164
|
}
|
|
2953
4165
|
|
|
2954
4166
|
// packages/managers/src/index.ts
|
|
4167
|
+
var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
|
|
4168
|
+
function snowflakeTime(id) {
|
|
4169
|
+
return Number((BigInt(id) >> 22n) + 1420070400000n);
|
|
4170
|
+
}
|
|
4171
|
+
|
|
2955
4172
|
class ChannelManager extends Manager {
|
|
2956
4173
|
#rest;
|
|
2957
4174
|
#context;
|
|
2958
4175
|
#messageManagers = new Map;
|
|
2959
|
-
|
|
4176
|
+
#messageCache;
|
|
4177
|
+
constructor(rest, options = {}) {
|
|
2960
4178
|
super();
|
|
2961
4179
|
this.#rest = rest;
|
|
4180
|
+
this.#messageCache = options.messageCache;
|
|
2962
4181
|
this.#context = {
|
|
2963
4182
|
sendMessage: (channelId, options) => this.send(channelId, options),
|
|
2964
4183
|
editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
|
|
@@ -2977,27 +4196,29 @@ class ChannelManager extends Manager {
|
|
|
2977
4196
|
messages(channelId) {
|
|
2978
4197
|
let manager = this.#messageManagers.get(channelId);
|
|
2979
4198
|
if (!manager) {
|
|
2980
|
-
manager = new MessageManager(this.#rest, this.#context, channelId);
|
|
4199
|
+
manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
|
|
2981
4200
|
this.#messageManagers.set(channelId, manager);
|
|
2982
4201
|
}
|
|
2983
4202
|
return manager;
|
|
2984
4203
|
}
|
|
2985
4204
|
permissionOverwrites(channelId) {
|
|
2986
|
-
return new PermissionOverwriteManager(this.#rest, channelId);
|
|
4205
|
+
return new PermissionOverwriteManager(this.#rest, channelId, () => this.get(channelId)?.permissionOverwrites);
|
|
2987
4206
|
}
|
|
2988
4207
|
threads(channelId) {
|
|
2989
4208
|
return new ThreadManager(this.#rest, this.#context, channelId);
|
|
2990
4209
|
}
|
|
2991
|
-
|
|
2992
|
-
return this.
|
|
4210
|
+
fetch(channelId) {
|
|
4211
|
+
return this.fetchOnce(channelId, async () => createChannel(await this.#rest.get(Routes.channel(channelId)), this.#context), (channel) => this.#merge(channel));
|
|
2993
4212
|
}
|
|
2994
4213
|
async resolve(channelId) {
|
|
2995
4214
|
return this.get(channelId) ?? this.fetch(channelId);
|
|
2996
4215
|
}
|
|
2997
4216
|
upsert(data) {
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
4217
|
+
return this.#merge(createChannel(data, this.#context));
|
|
4218
|
+
}
|
|
4219
|
+
#merge(channel) {
|
|
4220
|
+
const existing = this.get(channel.id);
|
|
4221
|
+
if (existing && existing.type === channel.type) {
|
|
3001
4222
|
Object.assign(existing, channel);
|
|
3002
4223
|
return existing;
|
|
3003
4224
|
}
|
|
@@ -3007,6 +4228,37 @@ class ChannelManager extends Manager {
|
|
|
3007
4228
|
update(channel) {
|
|
3008
4229
|
return this.set(channel.id, channel);
|
|
3009
4230
|
}
|
|
4231
|
+
deleteGuildChannels(guildId) {
|
|
4232
|
+
let removed = 0;
|
|
4233
|
+
for (const channel of this.values())
|
|
4234
|
+
if (channel.guildId === guildId && this.delete(channel.id))
|
|
4235
|
+
removed++;
|
|
4236
|
+
return removed;
|
|
4237
|
+
}
|
|
4238
|
+
async endPoll(channelId, messageId) {
|
|
4239
|
+
return this.messages(channelId).upsert(await this.#rest.post(Routes.pollExpire(channelId, messageId)));
|
|
4240
|
+
}
|
|
4241
|
+
async fetchPollVoters(channelId, messageId, answerId, options = {}) {
|
|
4242
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100))
|
|
4243
|
+
throw new RangeError("Poll voter limit must be 1-100.");
|
|
4244
|
+
const params = new URLSearchParams;
|
|
4245
|
+
if (options.after)
|
|
4246
|
+
params.set("after", options.after);
|
|
4247
|
+
if (options.limit !== undefined)
|
|
4248
|
+
params.set("limit", String(options.limit));
|
|
4249
|
+
const suffix = params.toString();
|
|
4250
|
+
const { users } = await this.#rest.get(`${Routes.pollAnswerVoters(channelId, messageId, answerId)}${suffix ? `?${suffix}` : ""}`);
|
|
4251
|
+
return users.map((user) => new User(user));
|
|
4252
|
+
}
|
|
4253
|
+
async sendSoundboardSound(channelId, options) {
|
|
4254
|
+
await this.#rest.post(Routes.sendSoundboardSound(channelId), {
|
|
4255
|
+
sound_id: options.soundId,
|
|
4256
|
+
source_guild_id: options.sourceGuildId
|
|
4257
|
+
});
|
|
4258
|
+
}
|
|
4259
|
+
cachedMessages(channelId) {
|
|
4260
|
+
return this.#messageManagers.get(channelId);
|
|
4261
|
+
}
|
|
3010
4262
|
async create(guildId, options) {
|
|
3011
4263
|
return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
|
|
3012
4264
|
}
|
|
@@ -3050,7 +4302,7 @@ class ChannelManager extends Manager {
|
|
|
3050
4302
|
return this.messages(data.channel_id).upsert(data);
|
|
3051
4303
|
}
|
|
3052
4304
|
async editMessage(channelId, messageId, options) {
|
|
3053
|
-
return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), options));
|
|
4305
|
+
return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options)));
|
|
3054
4306
|
}
|
|
3055
4307
|
async deleteMessage(channelId, messageId) {
|
|
3056
4308
|
await this.#rest.delete(Routes.message(channelId, messageId));
|
|
@@ -3063,15 +4315,37 @@ class ChannelManager extends Manager {
|
|
|
3063
4315
|
return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
|
|
3064
4316
|
}
|
|
3065
4317
|
async bulkDeleteMessages(channelId, messageIds) {
|
|
3066
|
-
const ids = [...messageIds];
|
|
3067
|
-
if (ids.length <
|
|
3068
|
-
throw new RangeError("bulkDelete requires between
|
|
4318
|
+
const ids = [...new Set(messageIds)];
|
|
4319
|
+
if (ids.length < 1 || ids.length > 100)
|
|
4320
|
+
throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
|
|
4321
|
+
if (ids.length === 1)
|
|
4322
|
+
return this.deleteMessage(channelId, ids[0]);
|
|
4323
|
+
const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
|
|
4324
|
+
const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
|
|
4325
|
+
if (tooOld.length)
|
|
4326
|
+
throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
|
|
3069
4327
|
await this.#rest.post(Routes.channelBulkDelete(channelId), {
|
|
3070
4328
|
messages: ids
|
|
3071
4329
|
});
|
|
3072
4330
|
for (const id of ids)
|
|
3073
4331
|
this.messages(channelId).delete(id);
|
|
3074
4332
|
}
|
|
4333
|
+
async* iterateMessages(channelId, options = {}) {
|
|
4334
|
+
let before = options.before;
|
|
4335
|
+
let remaining = options.limit ?? Infinity;
|
|
4336
|
+
while (remaining > 0) {
|
|
4337
|
+
const page = await this.fetchMessages(channelId, {
|
|
4338
|
+
before,
|
|
4339
|
+
limit: Math.min(100, remaining)
|
|
4340
|
+
});
|
|
4341
|
+
for (const message of page)
|
|
4342
|
+
yield message;
|
|
4343
|
+
remaining -= page.length;
|
|
4344
|
+
if (page.length < 100)
|
|
4345
|
+
return;
|
|
4346
|
+
before = page.at(-1).id;
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
3075
4349
|
async addReaction(channelId, messageId, emoji) {
|
|
3076
4350
|
await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
|
|
3077
4351
|
}
|
|
@@ -3167,6 +4441,8 @@ class GatewaySession {
|
|
|
3167
4441
|
return false;
|
|
3168
4442
|
if (!Number.isInteger(sequence))
|
|
3169
4443
|
return false;
|
|
4444
|
+
if (this.#sequence !== null && sequence < this.#sequence)
|
|
4445
|
+
return false;
|
|
3170
4446
|
this.#sequence = sequence;
|
|
3171
4447
|
return true;
|
|
3172
4448
|
}
|
|
@@ -3265,8 +4541,11 @@ class GatewayHeartbeat {
|
|
|
3265
4541
|
this.#clearBeatTimers();
|
|
3266
4542
|
this.#interval = interval;
|
|
3267
4543
|
this.#acknowledged = true;
|
|
3268
|
-
this.#initialTimer = setTimeout(() =>
|
|
3269
|
-
|
|
4544
|
+
this.#initialTimer = setTimeout(() => {
|
|
4545
|
+
this.#initialTimer = undefined;
|
|
4546
|
+
this.sendHeartbeat();
|
|
4547
|
+
this.#timer = setInterval(() => this.sendHeartbeat(), interval);
|
|
4548
|
+
}, Math.random() * interval);
|
|
3270
4549
|
}
|
|
3271
4550
|
stop() {
|
|
3272
4551
|
this.#clearBeatTimers();
|
|
@@ -3292,6 +4571,8 @@ class GatewayHeartbeat {
|
|
|
3292
4571
|
}, this.#options.ackTimeout);
|
|
3293
4572
|
}
|
|
3294
4573
|
acknowledge() {
|
|
4574
|
+
if (this.#acknowledged)
|
|
4575
|
+
return;
|
|
3295
4576
|
this.#acknowledged = true;
|
|
3296
4577
|
this.#latency = this.#now() - this.#sentAt;
|
|
3297
4578
|
this.#clearAckTimer();
|
|
@@ -3860,6 +5141,7 @@ class SendBudget {
|
|
|
3860
5141
|
}
|
|
3861
5142
|
|
|
3862
5143
|
// packages/ws/src/index.ts
|
|
5144
|
+
var RESUMABLE_CLOSE_CODE = 4900;
|
|
3863
5145
|
var DEFAULT_GATEWAY_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
3864
5146
|
|
|
3865
5147
|
class Gateway {
|
|
@@ -3945,7 +5227,7 @@ class Gateway {
|
|
|
3945
5227
|
} else {
|
|
3946
5228
|
this.#emitError(new GatewayError(`Gateway heartbeat acknowledgement timed out after ${timeout.elapsedMs}ms.`));
|
|
3947
5229
|
}
|
|
3948
|
-
this.#transport.close(
|
|
5230
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, timeout.type === "zombie" ? "Zombie Gateway connection" : "Heartbeat timeout");
|
|
3949
5231
|
}
|
|
3950
5232
|
connect(url = DEFAULT_GATEWAY_URL) {
|
|
3951
5233
|
if (this.state === "CLOSED" /* Closed */)
|
|
@@ -4081,7 +5363,7 @@ class Gateway {
|
|
|
4081
5363
|
this.#emit("heartbeatAck", action.data);
|
|
4082
5364
|
return;
|
|
4083
5365
|
case "reconnect":
|
|
4084
|
-
this.#transport.close(
|
|
5366
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, "Server requested reconnect");
|
|
4085
5367
|
return;
|
|
4086
5368
|
case "invalid-session": {
|
|
4087
5369
|
if (!action.resumable)
|
|
@@ -4275,6 +5557,7 @@ class Client extends EventEmitter2 {
|
|
|
4275
5557
|
channels;
|
|
4276
5558
|
stageInstances;
|
|
4277
5559
|
application;
|
|
5560
|
+
monetization;
|
|
4278
5561
|
get ws() {
|
|
4279
5562
|
return this.#gateway;
|
|
4280
5563
|
}
|
|
@@ -4306,6 +5589,7 @@ class Client extends EventEmitter2 {
|
|
|
4306
5589
|
return this.#gateway.requestGuildMembers(data);
|
|
4307
5590
|
}
|
|
4308
5591
|
#gateway;
|
|
5592
|
+
#cache;
|
|
4309
5593
|
#resourceContext;
|
|
4310
5594
|
constructor(options) {
|
|
4311
5595
|
super();
|
|
@@ -4313,9 +5597,18 @@ class Client extends EventEmitter2 {
|
|
|
4313
5597
|
if (!options.token?.trim())
|
|
4314
5598
|
throw new TypeError("Client token is required.");
|
|
4315
5599
|
this.rest = new REST({ token: options.token, ...options.rest });
|
|
5600
|
+
this.#cache = {
|
|
5601
|
+
users: true,
|
|
5602
|
+
members: true,
|
|
5603
|
+
roles: true,
|
|
5604
|
+
emojis: true,
|
|
5605
|
+
...options.cache
|
|
5606
|
+
};
|
|
4316
5607
|
this.users = new UserManager(this.rest);
|
|
4317
5608
|
this.guilds = new GuildManager(this.rest);
|
|
4318
|
-
this.channels = new ChannelManager(this.rest
|
|
5609
|
+
this.channels = new ChannelManager(this.rest, {
|
|
5610
|
+
messageCache: options.messageCache
|
|
5611
|
+
});
|
|
4319
5612
|
this.stageInstances = new StageInstanceManager(this.rest);
|
|
4320
5613
|
const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
|
|
4321
5614
|
this.application = { commands: placeholderAppCommands };
|
|
@@ -4331,8 +5624,32 @@ class Client extends EventEmitter2 {
|
|
|
4331
5624
|
removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
|
|
4332
5625
|
removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
|
|
4333
5626
|
pinMessage: (channelId, messageId) => this.channels.pinMessage(channelId, messageId),
|
|
4334
|
-
unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId)
|
|
5627
|
+
unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId),
|
|
5628
|
+
collectInteractions: (options) => this.createCollector("interactionCreate" /* InteractionCreate */, options),
|
|
5629
|
+
memberPermissions: (guildId, memberId, roleIds, channelId) => this.#memberPermissions(guildId, memberId, roleIds, channelId),
|
|
5630
|
+
kickMember: (guildId, userId, reason) => this.guilds.members(guildId).kick(userId, reason),
|
|
5631
|
+
banMember: (guildId, userId, options) => this.guilds.members(guildId).ban(userId, options),
|
|
5632
|
+
editMember: (guildId, userId, options, reason) => this.guilds.members(guildId).edit(userId, options, reason),
|
|
5633
|
+
addMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).addRole(userId, roleId, reason),
|
|
5634
|
+
removeMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).removeRole(userId, roleId, reason),
|
|
5635
|
+
editPermissionOverwrite: async (channelId, targetId, changes, options) => {
|
|
5636
|
+
const bits = { allow: 0n, deny: 0n, inherit: 0n };
|
|
5637
|
+
for (const [name, value] of Object.entries(changes)) {
|
|
5638
|
+
if (!/^[A-Za-z]+$/.test(name))
|
|
5639
|
+
throw new TypeError(`Unknown permission: ${name}`);
|
|
5640
|
+
let bit;
|
|
5641
|
+
try {
|
|
5642
|
+
bit = new PermissionSet(name).bitfield;
|
|
5643
|
+
} catch {
|
|
5644
|
+
throw new TypeError(`Unknown permission: ${name}`);
|
|
5645
|
+
}
|
|
5646
|
+
const key = value === true ? "allow" : value === false ? "deny" : "inherit";
|
|
5647
|
+
bits[key] |= bit;
|
|
5648
|
+
}
|
|
5649
|
+
return this.channels.permissionOverwrites(channelId).update(targetId, bits, options);
|
|
5650
|
+
}
|
|
4335
5651
|
};
|
|
5652
|
+
this.guilds.attachContext(this.#resourceContext);
|
|
4336
5653
|
this.#gateway = new Gateway({
|
|
4337
5654
|
token: options.token,
|
|
4338
5655
|
intents: options.intents,
|
|
@@ -4346,6 +5663,8 @@ class Client extends EventEmitter2 {
|
|
|
4346
5663
|
this.state = "ready";
|
|
4347
5664
|
const appId = ready.application?.id ?? this.user.id;
|
|
4348
5665
|
this.application.commands = new ApplicationCommandManager(this.rest, appId);
|
|
5666
|
+
if (this.monetization?.applicationId !== appId)
|
|
5667
|
+
this.monetization = new MonetizationManager(this.rest, appId);
|
|
4349
5668
|
this.emit("ready" /* Ready */, this.user);
|
|
4350
5669
|
});
|
|
4351
5670
|
this.#gateway.on("RESUMED", () => {
|
|
@@ -4362,19 +5681,46 @@ class Client extends EventEmitter2 {
|
|
|
4362
5681
|
this.emit("close" /* Close */, data);
|
|
4363
5682
|
});
|
|
4364
5683
|
this.#gateway.on("MESSAGE_CREATE", (data) => {
|
|
4365
|
-
const
|
|
4366
|
-
|
|
4367
|
-
this
|
|
4368
|
-
|
|
5684
|
+
const payload = data;
|
|
5685
|
+
const message = new Message(payload, this.#resourceContext);
|
|
5686
|
+
this.#observeMessage(message);
|
|
5687
|
+
if (payload.member && payload.guild_id && this.guilds.has(payload.guild_id))
|
|
5688
|
+
this.#upsertMember(payload.guild_id, {
|
|
5689
|
+
...payload.member,
|
|
5690
|
+
user: payload.member.user ?? payload.author
|
|
5691
|
+
});
|
|
5692
|
+
const cached = this.options.messageCache ? this.channels.messages(message.channelId).upsert(data) : message;
|
|
5693
|
+
this.emit("messageCreate" /* MessageCreate */, cached);
|
|
4369
5694
|
});
|
|
4370
5695
|
this.#gateway.on("MESSAGE_UPDATE", (data) => {
|
|
4371
5696
|
const message = new Message(data, this.#resourceContext);
|
|
4372
|
-
this
|
|
4373
|
-
this.
|
|
4374
|
-
|
|
5697
|
+
this.#observeMessage(message);
|
|
5698
|
+
const messages = this.channels.cachedMessages(message.channelId);
|
|
5699
|
+
const previous = messages?.cache.peek(message.id);
|
|
5700
|
+
if (previous)
|
|
5701
|
+
messages.cache.set(message.id, message);
|
|
5702
|
+
this.emit("messageUpdate" /* MessageUpdate */, message, previous);
|
|
5703
|
+
});
|
|
5704
|
+
this.#gateway.on("MESSAGE_DELETE", (data) => {
|
|
5705
|
+
const payload = data;
|
|
5706
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
5707
|
+
const removed = messages?.cache.peek(payload.id);
|
|
5708
|
+
messages?.delete(payload.id);
|
|
5709
|
+
this.emit("messageDelete" /* MessageDelete */, payload, removed);
|
|
5710
|
+
});
|
|
5711
|
+
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => {
|
|
5712
|
+
const payload = data;
|
|
5713
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
5714
|
+
const removed = [];
|
|
5715
|
+
if (messages)
|
|
5716
|
+
for (const id of payload.ids) {
|
|
5717
|
+
const message = messages.cache.peek(id);
|
|
5718
|
+
if (message)
|
|
5719
|
+
removed.push(message);
|
|
5720
|
+
messages.delete(id);
|
|
5721
|
+
}
|
|
5722
|
+
this.emit("messageDeleteBulk" /* MessageDeleteBulk */, payload, removed);
|
|
4375
5723
|
});
|
|
4376
|
-
this.#gateway.on("MESSAGE_DELETE", (data) => this.emit("messageDelete" /* MessageDelete */, data));
|
|
4377
|
-
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => this.emit("messageDeleteBulk" /* MessageDeleteBulk */, data));
|
|
4378
5724
|
this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
|
|
4379
5725
|
this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
|
|
4380
5726
|
this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
|
|
@@ -4388,20 +5734,27 @@ class Client extends EventEmitter2 {
|
|
|
4388
5734
|
return;
|
|
4389
5735
|
}
|
|
4390
5736
|
const wasCached = this.guilds.has(payload.id);
|
|
4391
|
-
|
|
4392
|
-
|
|
5737
|
+
this.guilds.patch(payload);
|
|
5738
|
+
for (const role of payload.roles ?? [])
|
|
5739
|
+
this.#upsertRole(payload.id, role);
|
|
5740
|
+
if (this.#cache.emojis) {
|
|
5741
|
+
const emojis = this.guilds.emojis(payload.id);
|
|
5742
|
+
for (const emoji of payload.emojis ?? [])
|
|
5743
|
+
emojis.upsert(emoji);
|
|
5744
|
+
}
|
|
4393
5745
|
for (const member of payload.members ?? [])
|
|
4394
|
-
this
|
|
5746
|
+
this.#upsertMember(payload.id, member);
|
|
5747
|
+
for (const state of payload.voice_states ?? [])
|
|
5748
|
+
this.#storeVoiceState(payload.id, state);
|
|
4395
5749
|
for (const channelData of [
|
|
4396
5750
|
...payload.channels ?? [],
|
|
4397
5751
|
...payload.threads ?? []
|
|
4398
5752
|
])
|
|
4399
|
-
this.channels.
|
|
5753
|
+
this.channels.upsert({ ...channelData, guild_id: payload.id });
|
|
4400
5754
|
this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
|
|
4401
5755
|
});
|
|
4402
5756
|
this.#gateway.on("GUILD_UPDATE", (data) => {
|
|
4403
|
-
|
|
4404
|
-
this.guilds.update(guild);
|
|
5757
|
+
this.guilds.patch(data);
|
|
4405
5758
|
this.emit("guildUpdate" /* GuildUpdate */, data);
|
|
4406
5759
|
});
|
|
4407
5760
|
this.#gateway.on("GUILD_DELETE", (data) => {
|
|
@@ -4411,45 +5764,158 @@ class Client extends EventEmitter2 {
|
|
|
4411
5764
|
return;
|
|
4412
5765
|
}
|
|
4413
5766
|
this.guilds.delete(payload.id);
|
|
5767
|
+
this.channels.deleteGuildChannels(payload.id);
|
|
4414
5768
|
this.emit("guildDelete" /* GuildDelete */, payload);
|
|
4415
5769
|
});
|
|
4416
5770
|
this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
|
|
4417
5771
|
const member = data;
|
|
4418
|
-
this
|
|
5772
|
+
this.#upsertMember(member.guild_id, member);
|
|
4419
5773
|
this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
|
|
4420
5774
|
});
|
|
4421
5775
|
this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
|
|
4422
5776
|
const member = data;
|
|
4423
|
-
this
|
|
5777
|
+
this.#upsertMember(member.guild_id, member);
|
|
4424
5778
|
this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
|
|
4425
5779
|
});
|
|
4426
|
-
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) =>
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
this.#gateway.on("
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
5780
|
+
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
|
|
5781
|
+
const member = data;
|
|
5782
|
+
this.guilds.members(member.guild_id).delete(member.user.id);
|
|
5783
|
+
this.emit("guildMemberRemove" /* GuildMemberRemove */, member);
|
|
5784
|
+
});
|
|
5785
|
+
this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => {
|
|
5786
|
+
const chunk = data;
|
|
5787
|
+
for (const member of chunk.members)
|
|
5788
|
+
this.#upsertMember(chunk.guild_id, member);
|
|
5789
|
+
this.emit("guildMembersChunk" /* GuildMembersChunk */, chunk);
|
|
5790
|
+
});
|
|
5791
|
+
this.#gateway.on("GUILD_BAN_ADD", (data) => {
|
|
5792
|
+
const ban = data;
|
|
5793
|
+
const bans = this.guilds.bans(ban.guild_id);
|
|
5794
|
+
bans.set(ban.user.id, {
|
|
5795
|
+
reason: bans.get(ban.user.id)?.reason ?? null,
|
|
5796
|
+
user: ban.user
|
|
5797
|
+
});
|
|
5798
|
+
this.guilds.members(ban.guild_id).delete(ban.user.id);
|
|
5799
|
+
this.emit("guildBanAdd" /* GuildBanAdd */, ban);
|
|
5800
|
+
});
|
|
5801
|
+
this.#gateway.on("GUILD_BAN_REMOVE", (data) => {
|
|
5802
|
+
const ban = data;
|
|
5803
|
+
this.guilds.bans(ban.guild_id).delete(ban.user.id);
|
|
5804
|
+
this.emit("guildBanRemove" /* GuildBanRemove */, ban);
|
|
5805
|
+
});
|
|
5806
|
+
this.#gateway.on("GUILD_ROLE_CREATE", (data) => {
|
|
5807
|
+
const event = data;
|
|
5808
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
5809
|
+
this.emit("guildRoleCreate" /* GuildRoleCreate */, event);
|
|
5810
|
+
});
|
|
5811
|
+
this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
|
|
5812
|
+
const event = data;
|
|
5813
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
5814
|
+
this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
|
|
5815
|
+
});
|
|
5816
|
+
this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
|
|
5817
|
+
const event = data;
|
|
5818
|
+
this.guilds.roles(event.guild_id).delete(event.role_id);
|
|
5819
|
+
this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
|
|
5820
|
+
});
|
|
5821
|
+
this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
|
|
5822
|
+
const event = data;
|
|
5823
|
+
if (this.#cache.emojis) {
|
|
5824
|
+
const emojis = this.guilds.emojis(event.guild_id);
|
|
5825
|
+
const current = new Set(event.emojis.map((emoji) => emoji.id));
|
|
5826
|
+
for (const id of [...emojis.cache.keys()])
|
|
5827
|
+
if (!current.has(id))
|
|
5828
|
+
emojis.delete(id);
|
|
5829
|
+
for (const emoji of event.emojis)
|
|
5830
|
+
emojis.upsert(emoji);
|
|
5831
|
+
}
|
|
5832
|
+
this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
|
|
5833
|
+
});
|
|
5834
|
+
this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
|
|
5835
|
+
const event = data;
|
|
5836
|
+
this.guilds.stickers(event.guild_id).sync(event.stickers);
|
|
5837
|
+
this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
|
|
5838
|
+
});
|
|
5839
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
|
|
5840
|
+
const sound = data;
|
|
5841
|
+
if (sound.guild_id)
|
|
5842
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
5843
|
+
this.emit("soundboardSoundCreate" /* SoundboardSoundCreate */, sound);
|
|
5844
|
+
});
|
|
5845
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_UPDATE", (data) => {
|
|
5846
|
+
const sound = data;
|
|
5847
|
+
if (sound.guild_id)
|
|
5848
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
5849
|
+
this.emit("soundboardSoundUpdate" /* SoundboardSoundUpdate */, sound);
|
|
5850
|
+
});
|
|
5851
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_DELETE", (data) => {
|
|
5852
|
+
const event = data;
|
|
5853
|
+
this.guilds.soundboard(event.guild_id).delete(event.sound_id);
|
|
5854
|
+
this.emit("soundboardSoundDelete" /* SoundboardSoundDelete */, event);
|
|
5855
|
+
});
|
|
5856
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUNDS_UPDATE", (data) => {
|
|
5857
|
+
const event = data;
|
|
5858
|
+
const sounds = this.guilds.soundboard(event.guild_id);
|
|
5859
|
+
sounds.clear();
|
|
5860
|
+
for (const sound of event.soundboard_sounds)
|
|
5861
|
+
sounds.set(sound.sound_id, sound);
|
|
5862
|
+
this.emit("soundboardSoundsUpdate" /* SoundboardSoundsUpdate */, event);
|
|
5863
|
+
});
|
|
5864
|
+
this.#gateway.on("ENTITLEMENT_CREATE", (data) => {
|
|
5865
|
+
const entitlement = data;
|
|
5866
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
5867
|
+
this.emit("entitlementCreate" /* EntitlementCreate */, entitlement);
|
|
5868
|
+
});
|
|
5869
|
+
this.#gateway.on("ENTITLEMENT_UPDATE", (data) => {
|
|
5870
|
+
const entitlement = data;
|
|
5871
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
5872
|
+
this.emit("entitlementUpdate" /* EntitlementUpdate */, entitlement);
|
|
5873
|
+
});
|
|
5874
|
+
this.#gateway.on("ENTITLEMENT_DELETE", (data) => {
|
|
5875
|
+
const entitlement = data;
|
|
5876
|
+
this.monetization?.delete(entitlement.id);
|
|
5877
|
+
this.emit("entitlementDelete" /* EntitlementDelete */, entitlement);
|
|
5878
|
+
});
|
|
4435
5879
|
this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
|
|
4436
|
-
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) =>
|
|
4437
|
-
|
|
4438
|
-
|
|
5880
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => {
|
|
5881
|
+
const event = data;
|
|
5882
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
5883
|
+
this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, event);
|
|
5884
|
+
});
|
|
5885
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => {
|
|
5886
|
+
const event = data;
|
|
5887
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
5888
|
+
this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, event);
|
|
5889
|
+
});
|
|
5890
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => {
|
|
5891
|
+
const event = data;
|
|
5892
|
+
this.guilds.scheduledEvents(event.guild_id).delete(event.id);
|
|
5893
|
+
this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, event);
|
|
5894
|
+
});
|
|
4439
5895
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
|
|
4440
5896
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_REMOVE", (data) => this.emit("guildScheduledEventUserRemove" /* GuildScheduledEventUserRemove */, data));
|
|
4441
|
-
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) =>
|
|
4442
|
-
|
|
4443
|
-
|
|
5897
|
+
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => {
|
|
5898
|
+
const rule = data;
|
|
5899
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
5900
|
+
this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, rule);
|
|
5901
|
+
});
|
|
5902
|
+
this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => {
|
|
5903
|
+
const rule = data;
|
|
5904
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
5905
|
+
this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, rule);
|
|
5906
|
+
});
|
|
5907
|
+
this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => {
|
|
5908
|
+
const rule = data;
|
|
5909
|
+
this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);
|
|
5910
|
+
this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
|
|
5911
|
+
});
|
|
4444
5912
|
this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
|
|
4445
5913
|
this.#gateway.on("CHANNEL_CREATE", (data) => {
|
|
4446
|
-
const channel =
|
|
4447
|
-
this.channels.update(channel);
|
|
5914
|
+
const channel = this.channels.upsert(data);
|
|
4448
5915
|
this.emit("channelCreate" /* ChannelCreate */, channel);
|
|
4449
5916
|
});
|
|
4450
5917
|
this.#gateway.on("CHANNEL_UPDATE", (data) => {
|
|
4451
|
-
const channel =
|
|
4452
|
-
this.channels.update(channel);
|
|
5918
|
+
const channel = this.channels.upsert(data);
|
|
4453
5919
|
this.emit("channelUpdate" /* ChannelUpdate */, channel);
|
|
4454
5920
|
});
|
|
4455
5921
|
this.#gateway.on("CHANNEL_DELETE", (data) => {
|
|
@@ -4459,13 +5925,11 @@ class Client extends EventEmitter2 {
|
|
|
4459
5925
|
});
|
|
4460
5926
|
this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
|
|
4461
5927
|
this.#gateway.on("THREAD_CREATE", (data) => {
|
|
4462
|
-
const channel =
|
|
4463
|
-
this.channels.update(channel);
|
|
5928
|
+
const channel = this.channels.upsert(data);
|
|
4464
5929
|
this.emit("threadCreate" /* ThreadCreate */, channel);
|
|
4465
5930
|
});
|
|
4466
5931
|
this.#gateway.on("THREAD_UPDATE", (data) => {
|
|
4467
|
-
const channel =
|
|
4468
|
-
this.channels.update(channel);
|
|
5932
|
+
const channel = this.channels.upsert(data);
|
|
4469
5933
|
this.emit("threadUpdate" /* ThreadUpdate */, channel);
|
|
4470
5934
|
});
|
|
4471
5935
|
this.#gateway.on("THREAD_DELETE", (data) => {
|
|
@@ -4473,16 +5937,48 @@ class Client extends EventEmitter2 {
|
|
|
4473
5937
|
this.channels.delete(payload.id);
|
|
4474
5938
|
this.emit("threadDelete" /* ThreadDelete */, payload);
|
|
4475
5939
|
});
|
|
4476
|
-
this.#gateway.on("THREAD_LIST_SYNC", (data) =>
|
|
5940
|
+
this.#gateway.on("THREAD_LIST_SYNC", (data) => {
|
|
5941
|
+
const sync = data;
|
|
5942
|
+
for (const thread of sync.threads)
|
|
5943
|
+
this.channels.upsert({ ...thread, guild_id: sync.guild_id });
|
|
5944
|
+
this.emit("threadListSync" /* ThreadListSync */, sync);
|
|
5945
|
+
});
|
|
4477
5946
|
this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
|
|
4478
5947
|
this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
|
|
4479
|
-
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) =>
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
5948
|
+
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => {
|
|
5949
|
+
const stage = data;
|
|
5950
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
5951
|
+
this.emit("stageInstanceCreate" /* StageInstanceCreate */, stage);
|
|
5952
|
+
});
|
|
5953
|
+
this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => {
|
|
5954
|
+
const stage = data;
|
|
5955
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
5956
|
+
this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, stage);
|
|
5957
|
+
});
|
|
5958
|
+
this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => {
|
|
5959
|
+
const stage = data;
|
|
5960
|
+
this.stageInstances.delete(stage.channel_id);
|
|
5961
|
+
this.emit("stageInstanceDelete" /* StageInstanceDelete */, stage);
|
|
5962
|
+
});
|
|
5963
|
+
this.#gateway.on("INVITE_CREATE", (data) => {
|
|
5964
|
+
const invite = data;
|
|
5965
|
+
if (invite.guild_id)
|
|
5966
|
+
this.guilds.invites(invite.guild_id).set(invite.code, invite);
|
|
5967
|
+
this.emit("inviteCreate" /* InviteCreate */, invite);
|
|
5968
|
+
});
|
|
5969
|
+
this.#gateway.on("INVITE_DELETE", (data) => {
|
|
5970
|
+
const invite = data;
|
|
5971
|
+
if (invite.guild_id)
|
|
5972
|
+
this.guilds.invites(invite.guild_id).delete(invite.code);
|
|
5973
|
+
this.emit("inviteDelete" /* InviteDelete */, invite);
|
|
5974
|
+
});
|
|
4484
5975
|
this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
|
|
4485
|
-
this.#gateway.on("VOICE_STATE_UPDATE", (data) =>
|
|
5976
|
+
this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
|
|
5977
|
+
const state = data;
|
|
5978
|
+
if (state.guild_id)
|
|
5979
|
+
this.#storeVoiceState(state.guild_id, state);
|
|
5980
|
+
this.emit("voiceStateUpdate" /* VoiceStateUpdate */, state);
|
|
5981
|
+
});
|
|
4486
5982
|
this.#gateway.on("VOICE_SERVER_UPDATE", (data) => this.emit("voiceServerUpdate" /* VoiceServerUpdate */, data));
|
|
4487
5983
|
this.#gateway.on("PRESENCE_UPDATE", (data) => this.emit("presenceUpdate" /* PresenceUpdate */, data));
|
|
4488
5984
|
this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
|
|
@@ -4490,6 +5986,103 @@ class Client extends EventEmitter2 {
|
|
|
4490
5986
|
this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
|
|
4491
5987
|
this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
|
|
4492
5988
|
}
|
|
5989
|
+
#observeMessage(message) {
|
|
5990
|
+
if (!this.channels.has(message.channelId))
|
|
5991
|
+
this.channels.set(message.channelId, message.channel);
|
|
5992
|
+
if (this.#cache.users)
|
|
5993
|
+
this.#merge(this.users, message.author.id, message.author);
|
|
5994
|
+
}
|
|
5995
|
+
#upsertMember(guildId, data) {
|
|
5996
|
+
const member = new GuildMember({ ...data, guild_id: guildId }, this.#resourceContext);
|
|
5997
|
+
if (this.#cache.users)
|
|
5998
|
+
this.#merge(this.users, member.user.id, member.user);
|
|
5999
|
+
if (!this.#cache.members)
|
|
6000
|
+
return member;
|
|
6001
|
+
return this.#merge(this.guilds.members(guildId), member.user.id, member);
|
|
6002
|
+
}
|
|
6003
|
+
#storeVoiceState(guildId, state) {
|
|
6004
|
+
const states = this.guilds.voiceStates(guildId);
|
|
6005
|
+
if (state.channel_id)
|
|
6006
|
+
states.set(state.user_id, state);
|
|
6007
|
+
else
|
|
6008
|
+
states.delete(state.user_id);
|
|
6009
|
+
}
|
|
6010
|
+
#upsertRole(guildId, data) {
|
|
6011
|
+
if (!this.#cache.roles)
|
|
6012
|
+
return new Role(data);
|
|
6013
|
+
return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
|
|
6014
|
+
}
|
|
6015
|
+
#merge(manager, id, next) {
|
|
6016
|
+
const existing = manager.get(id);
|
|
6017
|
+
if (!existing) {
|
|
6018
|
+
manager.set(id, next);
|
|
6019
|
+
return next;
|
|
6020
|
+
}
|
|
6021
|
+
for (const [key, value] of Object.entries(next))
|
|
6022
|
+
if (value !== undefined)
|
|
6023
|
+
existing[key] = value;
|
|
6024
|
+
return existing;
|
|
6025
|
+
}
|
|
6026
|
+
createCollector(event, options = {}) {
|
|
6027
|
+
const collector = new Collector(options);
|
|
6028
|
+
let order = 0;
|
|
6029
|
+
const listener = (...args) => {
|
|
6030
|
+
const item = args[0];
|
|
6031
|
+
const id = item?.id;
|
|
6032
|
+
const key = options.key?.(item) ?? (typeof id === "string" ? id : String(order++));
|
|
6033
|
+
collector.handle(key, item).catch((error) => this.emit("error" /* Error */, error instanceof Error ? error : new Error(String(error))));
|
|
6034
|
+
};
|
|
6035
|
+
this.on(event, listener);
|
|
6036
|
+
collector.onDispose(() => this.off(event, listener));
|
|
6037
|
+
return collector;
|
|
6038
|
+
}
|
|
6039
|
+
get resourceContext() {
|
|
6040
|
+
return this.#resourceContext;
|
|
6041
|
+
}
|
|
6042
|
+
#memberPermissions(guildId, memberId, roleIds, channelId) {
|
|
6043
|
+
const guild = this.guilds.get(guildId);
|
|
6044
|
+
if (!guild)
|
|
6045
|
+
return null;
|
|
6046
|
+
let channel = channelId ? this.channels.get(channelId) : undefined;
|
|
6047
|
+
if (channelId) {
|
|
6048
|
+
if (channel?.isThread())
|
|
6049
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
6050
|
+
if (!channel || channel.guildId !== guildId)
|
|
6051
|
+
return null;
|
|
6052
|
+
}
|
|
6053
|
+
return computePermissions({
|
|
6054
|
+
guildId,
|
|
6055
|
+
ownerId: guild.ownerId,
|
|
6056
|
+
memberId,
|
|
6057
|
+
memberRoleIds: [...roleIds],
|
|
6058
|
+
roles: this.guilds.roles(guildId).values(),
|
|
6059
|
+
overwrites: channel?.permissionOverwrites
|
|
6060
|
+
});
|
|
6061
|
+
}
|
|
6062
|
+
permissionsFor(memberId, guildOrChannelId) {
|
|
6063
|
+
let channel = this.channels.get(guildOrChannelId);
|
|
6064
|
+
if (channel?.isThread()) {
|
|
6065
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
6066
|
+
if (!channel)
|
|
6067
|
+
return null;
|
|
6068
|
+
}
|
|
6069
|
+
const guildId = channel?.guildId ?? guildOrChannelId;
|
|
6070
|
+
const guild = this.guilds.get(guildId);
|
|
6071
|
+
const member = this.guilds.members(guildId).get(memberId);
|
|
6072
|
+
if (!guild || !member)
|
|
6073
|
+
return null;
|
|
6074
|
+
return computePermissions({
|
|
6075
|
+
guildId,
|
|
6076
|
+
ownerId: guild.ownerId,
|
|
6077
|
+
memberId,
|
|
6078
|
+
memberRoleIds: member.roleIds,
|
|
6079
|
+
roles: this.guilds.roles(guildId).values(),
|
|
6080
|
+
overwrites: channel?.permissionOverwrites
|
|
6081
|
+
});
|
|
6082
|
+
}
|
|
6083
|
+
fetchDefaultSoundboardSounds() {
|
|
6084
|
+
return this.rest.get(Routes.soundboardDefaultSounds());
|
|
6085
|
+
}
|
|
4493
6086
|
async login(token) {
|
|
4494
6087
|
if (this.state === "destroyed")
|
|
4495
6088
|
throw new Error("Cannot login a destroyed client.");
|
|
@@ -4509,12 +6102,21 @@ class Client extends EventEmitter2 {
|
|
|
4509
6102
|
this.#gateway.close();
|
|
4510
6103
|
}
|
|
4511
6104
|
postInteractionResponse(id, token, response) {
|
|
4512
|
-
|
|
6105
|
+
const json = response.toJSON();
|
|
6106
|
+
const upload = json.data ? toRequest(json.data) : undefined;
|
|
6107
|
+
if (upload && typeof upload === "object" && "files" in upload) {
|
|
6108
|
+
const { body, files } = upload;
|
|
6109
|
+
return this.rest.post(Routes.interactionCallback(id, token), {
|
|
6110
|
+
body: { ...json, data: body },
|
|
6111
|
+
files
|
|
6112
|
+
});
|
|
6113
|
+
}
|
|
6114
|
+
return this.rest.post(Routes.interactionCallback(id, token), json);
|
|
4513
6115
|
}
|
|
4514
6116
|
editInteractionReply(token, data) {
|
|
4515
6117
|
if (!this.user)
|
|
4516
6118
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
4517
|
-
return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), data);
|
|
6119
|
+
return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data));
|
|
4518
6120
|
}
|
|
4519
6121
|
deleteInteractionReply(token) {
|
|
4520
6122
|
if (!this.user)
|
|
@@ -4524,7 +6126,15 @@ class Client extends EventEmitter2 {
|
|
|
4524
6126
|
followUpInteraction(token, data) {
|
|
4525
6127
|
if (!this.user)
|
|
4526
6128
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
4527
|
-
return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);
|
|
6129
|
+
return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data));
|
|
6130
|
+
}
|
|
6131
|
+
interactionWebhookMessage(method, applicationId, token, messageId, data) {
|
|
6132
|
+
const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
|
|
6133
|
+
if (method === "GET")
|
|
6134
|
+
return this.rest.get(path);
|
|
6135
|
+
if (method === "PATCH")
|
|
6136
|
+
return this.rest.patch(path, data);
|
|
6137
|
+
return this.rest.delete(path);
|
|
4528
6138
|
}
|
|
4529
6139
|
fetchWebhook(id, token) {
|
|
4530
6140
|
return this.rest.get(token ? `/webhooks/${id}/${token}` : `/webhooks/${id}`);
|
|
@@ -4583,7 +6193,8 @@ export {
|
|
|
4583
6193
|
PermissionSet,
|
|
4584
6194
|
Permissions,
|
|
4585
6195
|
PermissionsBitField,
|
|
6196
|
+
computePermissions,
|
|
4586
6197
|
resolveGatewayIntents
|
|
4587
6198
|
};
|
|
4588
6199
|
|
|
4589
|
-
//# debugId=
|
|
6200
|
+
//# debugId=C58DF09843ED07E364756E2164756E21
|