lunibee 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/builders/components.d.ts +5 -0
- package/dist/builders/index.js +72 -12
- package/dist/builders/index.js.map +5 -5
- package/dist/collection/index.d.ts +68 -1
- package/dist/collection/index.js +334 -1
- package/dist/collection/index.js.map +3 -3
- package/dist/core/collector.d.ts +13 -0
- package/dist/core/events.d.ts +29 -3
- package/dist/core/index.d.ts +22 -8
- package/dist/core/index.js +1526 -124
- package/dist/core/index.js.map +26 -22
- package/dist/core/permissions.d.ts +48 -0
- package/dist/index.js +1578 -268
- package/dist/index.js.map +30 -29
- package/dist/managers/advanced.d.ts +116 -0
- package/dist/managers/base.d.ts +13 -2
- package/dist/managers/emoji.d.ts +1 -1
- package/dist/managers/guild.d.ts +28 -2
- package/dist/managers/index.d.ts +37 -5
- package/dist/managers/index.js +870 -152
- package/dist/managers/index.js.map +18 -16
- package/dist/managers/message.d.ts +10 -1
- package/dist/rest/errors.d.ts +33 -0
- package/dist/rest/index.d.ts +1 -1
- package/dist/rest/index.js +52 -6
- package/dist/rest/index.js.map +5 -5
- package/dist/rest/routes.d.ts +20 -0
- package/dist/sharding/index.d.ts +29 -0
- package/dist/sharding/index.js +99 -15
- package/dist/sharding/index.js.map +8 -8
- package/dist/structures/base.d.ts +2 -0
- package/dist/structures/index.js +96 -42
- package/dist/structures/index.js.map +10 -9
- package/dist/structures/interactions.d.ts +26 -0
- package/dist/types/gateway.d.ts +16 -0
- package/dist/types/index.d.ts +55 -1
- package/dist/types/index.js.map +2 -2
- package/dist/voice/index.d.ts +3 -0
- package/dist/voice/index.js +15 -1
- package/dist/voice/index.js.map +3 -3
- package/dist/ws/index.js +13 -5
- package/dist/ws/index.js.map +6 -6
- package/package.json +14 -14
package/dist/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++) {
|
|
@@ -419,6 +432,35 @@ class PermissionsBitField extends PermissionSet {
|
|
|
419
432
|
super(value);
|
|
420
433
|
}
|
|
421
434
|
}
|
|
435
|
+
var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
|
|
436
|
+
var bits = (value) => new PermissionSet(value).bitfield;
|
|
437
|
+
function computePermissions(context) {
|
|
438
|
+
if (context.ownerId !== undefined && context.ownerId === context.memberId)
|
|
439
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
440
|
+
const roles = new Map(context.roles.map((role) => [role.id, role]));
|
|
441
|
+
let base = bits(roles.get(context.guildId)?.permissions ?? 0n);
|
|
442
|
+
for (const id of context.memberRoleIds)
|
|
443
|
+
base |= bits(roles.get(id)?.permissions ?? 0n);
|
|
444
|
+
if (base & Permission.administrator)
|
|
445
|
+
return new PermissionSet(ALL_PERMISSIONS);
|
|
446
|
+
const overwrites = context.overwrites ?? [];
|
|
447
|
+
const everyone = overwrites.find((o) => o.id === context.guildId);
|
|
448
|
+
if (everyone)
|
|
449
|
+
base = base & ~bits(everyone.deny) | bits(everyone.allow);
|
|
450
|
+
const memberRoles = new Set(context.memberRoleIds);
|
|
451
|
+
let allow = 0n;
|
|
452
|
+
let deny = 0n;
|
|
453
|
+
for (const overwrite of overwrites)
|
|
454
|
+
if (overwrite.type === 0 /* Role */ && overwrite.id !== context.guildId && memberRoles.has(overwrite.id)) {
|
|
455
|
+
allow |= bits(overwrite.allow);
|
|
456
|
+
deny |= bits(overwrite.deny);
|
|
457
|
+
}
|
|
458
|
+
base = base & ~deny | allow;
|
|
459
|
+
const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
|
|
460
|
+
if (member)
|
|
461
|
+
base = base & ~bits(member.deny) | bits(member.allow);
|
|
462
|
+
return new PermissionSet(base);
|
|
463
|
+
}
|
|
422
464
|
// packages/core/src/events.ts
|
|
423
465
|
var ClientEvent;
|
|
424
466
|
((ClientEvent) => {
|
|
@@ -455,6 +497,13 @@ var ClientEvent;
|
|
|
455
497
|
ClientEvent["GuildRoleDelete"] = "guildRoleDelete";
|
|
456
498
|
ClientEvent["GuildEmojisUpdate"] = "guildEmojisUpdate";
|
|
457
499
|
ClientEvent["GuildStickersUpdate"] = "guildStickersUpdate";
|
|
500
|
+
ClientEvent["EntitlementCreate"] = "entitlementCreate";
|
|
501
|
+
ClientEvent["EntitlementUpdate"] = "entitlementUpdate";
|
|
502
|
+
ClientEvent["EntitlementDelete"] = "entitlementDelete";
|
|
503
|
+
ClientEvent["SoundboardSoundCreate"] = "soundboardSoundCreate";
|
|
504
|
+
ClientEvent["SoundboardSoundUpdate"] = "soundboardSoundUpdate";
|
|
505
|
+
ClientEvent["SoundboardSoundDelete"] = "soundboardSoundDelete";
|
|
506
|
+
ClientEvent["SoundboardSoundsUpdate"] = "soundboardSoundsUpdate";
|
|
458
507
|
ClientEvent["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
|
|
459
508
|
ClientEvent["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
|
|
460
509
|
ClientEvent["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
|
|
@@ -497,6 +546,9 @@ class Collector extends EventEmitter {
|
|
|
497
546
|
endReason;
|
|
498
547
|
totalProcessed = 0;
|
|
499
548
|
#timeoutTimer;
|
|
549
|
+
#idleTimer;
|
|
550
|
+
#onAbort = () => this.stop("abort");
|
|
551
|
+
#cleanup = [];
|
|
500
552
|
constructor(options = {}) {
|
|
501
553
|
super();
|
|
502
554
|
this.options = options;
|
|
@@ -505,6 +557,27 @@ class Collector extends EventEmitter {
|
|
|
505
557
|
this.stop("time");
|
|
506
558
|
}, options.time);
|
|
507
559
|
}
|
|
560
|
+
this.#resetIdle();
|
|
561
|
+
if (options.signal?.aborted)
|
|
562
|
+
this.stop("abort");
|
|
563
|
+
else
|
|
564
|
+
options.signal?.addEventListener("abort", this.#onAbort, {
|
|
565
|
+
once: true
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
onDispose(cleanup) {
|
|
569
|
+
if (this.ended)
|
|
570
|
+
cleanup();
|
|
571
|
+
else
|
|
572
|
+
this.#cleanup.push(cleanup);
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
#resetIdle() {
|
|
576
|
+
if (!this.options.idle || this.options.idle <= 0)
|
|
577
|
+
return;
|
|
578
|
+
if (this.#idleTimer)
|
|
579
|
+
clearTimeout(this.#idleTimer);
|
|
580
|
+
this.#idleTimer = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
508
581
|
}
|
|
509
582
|
async handle(key, item) {
|
|
510
583
|
if (this.ended)
|
|
@@ -522,6 +595,7 @@ class Collector extends EventEmitter {
|
|
|
522
595
|
return false;
|
|
523
596
|
}
|
|
524
597
|
this.collected.set(key, item);
|
|
598
|
+
this.#resetIdle();
|
|
525
599
|
this.emit("collect", item);
|
|
526
600
|
if (this.options.max && this.collected.size >= this.options.max) {
|
|
527
601
|
this.stop("limit");
|
|
@@ -540,9 +614,53 @@ class Collector extends EventEmitter {
|
|
|
540
614
|
this.endReason = reason;
|
|
541
615
|
if (this.#timeoutTimer)
|
|
542
616
|
clearTimeout(this.#timeoutTimer);
|
|
617
|
+
if (this.#idleTimer)
|
|
618
|
+
clearTimeout(this.#idleTimer);
|
|
619
|
+
this.options.signal?.removeEventListener("abort", this.#onAbort);
|
|
620
|
+
for (const cleanup of this.#cleanup.splice(0)) {
|
|
621
|
+
try {
|
|
622
|
+
cleanup();
|
|
623
|
+
} catch {}
|
|
624
|
+
}
|
|
543
625
|
this.emit("end", this.collected, reason);
|
|
544
626
|
this.removeAllListeners();
|
|
545
627
|
}
|
|
628
|
+
wait() {
|
|
629
|
+
if (this.ended)
|
|
630
|
+
return Promise.resolve(this.collected);
|
|
631
|
+
return new Promise((resolve) => this.once("end", (collected) => resolve(collected)));
|
|
632
|
+
}
|
|
633
|
+
async* [Symbol.asyncIterator]() {
|
|
634
|
+
const queue = [];
|
|
635
|
+
let wake;
|
|
636
|
+
const onCollect = (item) => {
|
|
637
|
+
queue.push(item);
|
|
638
|
+
wake?.();
|
|
639
|
+
};
|
|
640
|
+
const onEnd = () => wake?.();
|
|
641
|
+
if (!this.ended) {
|
|
642
|
+
this.on("collect", onCollect);
|
|
643
|
+
this.on("end", onEnd);
|
|
644
|
+
}
|
|
645
|
+
try {
|
|
646
|
+
for (;; ) {
|
|
647
|
+
if (queue.length > 0) {
|
|
648
|
+
yield queue.shift();
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (this.ended)
|
|
652
|
+
return;
|
|
653
|
+
await new Promise((resolve) => wake = resolve);
|
|
654
|
+
wake = undefined;
|
|
655
|
+
}
|
|
656
|
+
} finally {
|
|
657
|
+
this.off("collect", onCollect);
|
|
658
|
+
this.off("end", onEnd);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
[Symbol.dispose]() {
|
|
662
|
+
this.stop("disposed");
|
|
663
|
+
}
|
|
546
664
|
next() {
|
|
547
665
|
return new Promise((resolve, reject) => {
|
|
548
666
|
if (this.ended) {
|
|
@@ -686,7 +804,340 @@ var InteractionResponseType = {
|
|
|
686
804
|
Modal: 9
|
|
687
805
|
};
|
|
688
806
|
// packages/collection/src/index.ts
|
|
807
|
+
class RecencyList {
|
|
808
|
+
#nodes = new Map;
|
|
809
|
+
#oldest;
|
|
810
|
+
#newest;
|
|
811
|
+
get size() {
|
|
812
|
+
return this.#nodes.size;
|
|
813
|
+
}
|
|
814
|
+
oldest() {
|
|
815
|
+
return this.#oldest?.key;
|
|
816
|
+
}
|
|
817
|
+
touch(key) {
|
|
818
|
+
const node = this.#nodes.get(key);
|
|
819
|
+
if (node)
|
|
820
|
+
return this.#moveNewest(node);
|
|
821
|
+
const created = { key, older: this.#newest };
|
|
822
|
+
if (this.#newest)
|
|
823
|
+
this.#newest.newer = created;
|
|
824
|
+
else
|
|
825
|
+
this.#oldest = created;
|
|
826
|
+
this.#newest = created;
|
|
827
|
+
this.#nodes.set(key, created);
|
|
828
|
+
}
|
|
829
|
+
promote(key) {
|
|
830
|
+
const node = this.#nodes.get(key);
|
|
831
|
+
if (node)
|
|
832
|
+
this.#moveNewest(node);
|
|
833
|
+
}
|
|
834
|
+
delete(key) {
|
|
835
|
+
const node = this.#nodes.get(key);
|
|
836
|
+
if (!node)
|
|
837
|
+
return false;
|
|
838
|
+
this.#unlink(node);
|
|
839
|
+
this.#nodes.delete(key);
|
|
840
|
+
return true;
|
|
841
|
+
}
|
|
842
|
+
clear() {
|
|
843
|
+
this.#nodes.clear();
|
|
844
|
+
this.#oldest = this.#newest = undefined;
|
|
845
|
+
}
|
|
846
|
+
#unlink(node) {
|
|
847
|
+
if (node.older)
|
|
848
|
+
node.older.newer = node.newer;
|
|
849
|
+
else
|
|
850
|
+
this.#oldest = node.newer;
|
|
851
|
+
if (node.newer)
|
|
852
|
+
node.newer.older = node.older;
|
|
853
|
+
else
|
|
854
|
+
this.#newest = node.older;
|
|
855
|
+
node.older = node.newer = undefined;
|
|
856
|
+
}
|
|
857
|
+
#moveNewest(node) {
|
|
858
|
+
if (node === this.#newest)
|
|
859
|
+
return;
|
|
860
|
+
this.#unlink(node);
|
|
861
|
+
node.older = this.#newest;
|
|
862
|
+
if (this.#newest)
|
|
863
|
+
this.#newest.newer = node;
|
|
864
|
+
else
|
|
865
|
+
this.#oldest = node;
|
|
866
|
+
this.#newest = node;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
function assertTTL(ttl) {
|
|
870
|
+
if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
|
|
871
|
+
throw new RangeError("TTL must be a positive number, or omitted.");
|
|
872
|
+
}
|
|
873
|
+
|
|
689
874
|
class Collection extends Map {
|
|
875
|
+
#ttl;
|
|
876
|
+
#maxSize;
|
|
877
|
+
#onEvict;
|
|
878
|
+
#expiry = new Map;
|
|
879
|
+
#lru = new RecencyList;
|
|
880
|
+
#stats = {
|
|
881
|
+
hits: 0,
|
|
882
|
+
misses: 0,
|
|
883
|
+
expired: 0,
|
|
884
|
+
evicted: 0
|
|
885
|
+
};
|
|
886
|
+
#heap = [];
|
|
887
|
+
#timer;
|
|
888
|
+
#armedFor = Infinity;
|
|
889
|
+
constructor(entries, options = {}) {
|
|
890
|
+
super();
|
|
891
|
+
assertTTL(options.ttl);
|
|
892
|
+
if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
|
|
893
|
+
throw new RangeError("maxSize must be a positive integer.");
|
|
894
|
+
this.#ttl = options.ttl;
|
|
895
|
+
this.#maxSize = options.maxSize;
|
|
896
|
+
this.#onEvict = options.onEvict;
|
|
897
|
+
if (entries)
|
|
898
|
+
for (const [key, value] of entries)
|
|
899
|
+
this.set(key, value);
|
|
900
|
+
}
|
|
901
|
+
set(key, value, ttl) {
|
|
902
|
+
assertTTL(ttl);
|
|
903
|
+
const window = ttl ?? this.#ttl;
|
|
904
|
+
if (this.#maxSize !== undefined) {
|
|
905
|
+
this.#lru.touch(key);
|
|
906
|
+
}
|
|
907
|
+
super.set(key, value);
|
|
908
|
+
if (window !== undefined)
|
|
909
|
+
this.#schedule(key, window);
|
|
910
|
+
else if (this.#expiry.size > 0)
|
|
911
|
+
this.#expiry.delete(key);
|
|
912
|
+
this.#enforceCap();
|
|
913
|
+
return this;
|
|
914
|
+
}
|
|
915
|
+
setWithoutTTL(key, value) {
|
|
916
|
+
if (this.#expiry.size > 0)
|
|
917
|
+
this.#expiry.delete(key);
|
|
918
|
+
if (this.#lru.size > 0)
|
|
919
|
+
this.#lru.delete(key);
|
|
920
|
+
super.set(key, value);
|
|
921
|
+
return this;
|
|
922
|
+
}
|
|
923
|
+
get(key) {
|
|
924
|
+
if (this.#expireIfDue(key)) {
|
|
925
|
+
this.#stats.misses++;
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const value = super.get(key);
|
|
929
|
+
if (value === undefined && !super.has(key)) {
|
|
930
|
+
this.#stats.misses++;
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
this.#stats.hits++;
|
|
934
|
+
const expiry = this.#expiry.get(key);
|
|
935
|
+
if (expiry)
|
|
936
|
+
expiry.deadline = Date.now() + expiry.window;
|
|
937
|
+
this.#lru.promote(key);
|
|
938
|
+
return value;
|
|
939
|
+
}
|
|
940
|
+
peek(key) {
|
|
941
|
+
if (!this.#expireIfDue(key) && super.has(key)) {
|
|
942
|
+
this.#stats.hits++;
|
|
943
|
+
return super.get(key);
|
|
944
|
+
}
|
|
945
|
+
this.#stats.misses++;
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
get stats() {
|
|
949
|
+
return { ...this.#stats };
|
|
950
|
+
}
|
|
951
|
+
has(key) {
|
|
952
|
+
return !this.#expireIfDue(key) && super.has(key);
|
|
953
|
+
}
|
|
954
|
+
delete(key) {
|
|
955
|
+
if (this.#expireIfDue(key))
|
|
956
|
+
return false;
|
|
957
|
+
this.#expiry.delete(key);
|
|
958
|
+
this.#lru.delete(key);
|
|
959
|
+
return super.delete(key);
|
|
960
|
+
}
|
|
961
|
+
clear() {
|
|
962
|
+
super.clear();
|
|
963
|
+
this.#expiry.clear();
|
|
964
|
+
this.#lru.clear();
|
|
965
|
+
this.#heap.length = 0;
|
|
966
|
+
if (this.#timer)
|
|
967
|
+
clearTimeout(this.#timer);
|
|
968
|
+
this.#timer = undefined;
|
|
969
|
+
this.#armedFor = Infinity;
|
|
970
|
+
}
|
|
971
|
+
get size() {
|
|
972
|
+
this.purge();
|
|
973
|
+
return super.size;
|
|
974
|
+
}
|
|
975
|
+
entries() {
|
|
976
|
+
this.purge();
|
|
977
|
+
return super.entries();
|
|
978
|
+
}
|
|
979
|
+
keys() {
|
|
980
|
+
this.purge();
|
|
981
|
+
return super.keys();
|
|
982
|
+
}
|
|
983
|
+
values() {
|
|
984
|
+
this.purge();
|
|
985
|
+
return super.values();
|
|
986
|
+
}
|
|
987
|
+
[Symbol.iterator]() {
|
|
988
|
+
return this.entries();
|
|
989
|
+
}
|
|
990
|
+
forEach(callback, thisArg) {
|
|
991
|
+
this.purge();
|
|
992
|
+
super.forEach(callback, thisArg);
|
|
993
|
+
}
|
|
994
|
+
ttlRemaining(key) {
|
|
995
|
+
if (this.#expireIfDue(key))
|
|
996
|
+
return;
|
|
997
|
+
const expiry = this.#expiry.get(key);
|
|
998
|
+
return expiry && Math.max(0, expiry.deadline - Date.now());
|
|
999
|
+
}
|
|
1000
|
+
purge() {
|
|
1001
|
+
if (this.#expiry.size === 0)
|
|
1002
|
+
return 0;
|
|
1003
|
+
const now = Date.now();
|
|
1004
|
+
let removed = 0;
|
|
1005
|
+
const dropped = [];
|
|
1006
|
+
while (this.#nextDeadline() <= now) {
|
|
1007
|
+
const due = this.#heapPop();
|
|
1008
|
+
dropped.push([due.key, super.get(due.key)]);
|
|
1009
|
+
this.#remove(due.key);
|
|
1010
|
+
removed++;
|
|
1011
|
+
}
|
|
1012
|
+
this.#stats.expired += removed;
|
|
1013
|
+
this.#rearm();
|
|
1014
|
+
for (const [key, value] of dropped)
|
|
1015
|
+
this.#notify(key, value, "expired");
|
|
1016
|
+
return removed;
|
|
1017
|
+
}
|
|
1018
|
+
#expireIfDue(key) {
|
|
1019
|
+
const expiry = this.#expiry.get(key);
|
|
1020
|
+
if (!expiry || expiry.deadline > Date.now())
|
|
1021
|
+
return false;
|
|
1022
|
+
const value = super.get(key);
|
|
1023
|
+
this.#remove(key);
|
|
1024
|
+
this.#stats.expired++;
|
|
1025
|
+
this.#notify(key, value, "expired");
|
|
1026
|
+
return true;
|
|
1027
|
+
}
|
|
1028
|
+
#remove(key) {
|
|
1029
|
+
this.#expiry.delete(key);
|
|
1030
|
+
this.#lru.delete(key);
|
|
1031
|
+
super.delete(key);
|
|
1032
|
+
}
|
|
1033
|
+
#notify(key, value, reason) {
|
|
1034
|
+
if (!this.#onEvict)
|
|
1035
|
+
return;
|
|
1036
|
+
try {
|
|
1037
|
+
this.#onEvict(key, value, reason);
|
|
1038
|
+
} catch {}
|
|
1039
|
+
}
|
|
1040
|
+
#enforceCap() {
|
|
1041
|
+
if (this.#maxSize === undefined)
|
|
1042
|
+
return;
|
|
1043
|
+
while (this.#lru.size > this.#maxSize) {
|
|
1044
|
+
const oldest = this.#lru.oldest();
|
|
1045
|
+
const value = super.get(oldest);
|
|
1046
|
+
this.#remove(oldest);
|
|
1047
|
+
this.#stats.evicted++;
|
|
1048
|
+
this.#notify(oldest, value, "evicted");
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
#schedule(key, window) {
|
|
1052
|
+
const deadline = Date.now() + window;
|
|
1053
|
+
const expiry = this.#expiry.get(key);
|
|
1054
|
+
if (expiry) {
|
|
1055
|
+
expiry.deadline = deadline;
|
|
1056
|
+
expiry.window = window;
|
|
1057
|
+
if (deadline >= expiry.filed)
|
|
1058
|
+
return;
|
|
1059
|
+
expiry.filed = deadline;
|
|
1060
|
+
} else
|
|
1061
|
+
this.#expiry.set(key, { deadline, window, filed: deadline });
|
|
1062
|
+
this.#heapPush({ key, deadline });
|
|
1063
|
+
if (this.#heap.length > 2 * this.#expiry.size + 8)
|
|
1064
|
+
this.#compact();
|
|
1065
|
+
this.#rearm();
|
|
1066
|
+
}
|
|
1067
|
+
#nextDeadline() {
|
|
1068
|
+
for (;; ) {
|
|
1069
|
+
const top = this.#heap[0];
|
|
1070
|
+
if (top === undefined)
|
|
1071
|
+
return Infinity;
|
|
1072
|
+
const expiry = this.#expiry.get(top.key);
|
|
1073
|
+
if (!expiry || expiry.filed !== top.deadline) {
|
|
1074
|
+
this.#heapPop();
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
if (expiry.deadline === top.deadline)
|
|
1078
|
+
return top.deadline;
|
|
1079
|
+
this.#heapPop();
|
|
1080
|
+
expiry.filed = expiry.deadline;
|
|
1081
|
+
this.#heapPush({ key: top.key, deadline: expiry.deadline });
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
#compact() {
|
|
1085
|
+
const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
|
|
1086
|
+
this.#heap.length = 0;
|
|
1087
|
+
for (const record of live)
|
|
1088
|
+
this.#heapPush(record);
|
|
1089
|
+
}
|
|
1090
|
+
#rearm() {
|
|
1091
|
+
const deadline = this.#nextDeadline();
|
|
1092
|
+
if (this.#timer !== undefined && deadline >= this.#armedFor)
|
|
1093
|
+
return;
|
|
1094
|
+
if (this.#timer)
|
|
1095
|
+
clearTimeout(this.#timer);
|
|
1096
|
+
this.#timer = undefined;
|
|
1097
|
+
this.#armedFor = deadline;
|
|
1098
|
+
if (deadline === Infinity)
|
|
1099
|
+
return;
|
|
1100
|
+
this.#timer = setTimeout(() => {
|
|
1101
|
+
this.#timer = undefined;
|
|
1102
|
+
this.#armedFor = Infinity;
|
|
1103
|
+
this.purge();
|
|
1104
|
+
}, Math.max(0, deadline - Date.now()));
|
|
1105
|
+
this.#timer.unref?.();
|
|
1106
|
+
}
|
|
1107
|
+
#heapPush(record) {
|
|
1108
|
+
const heap = this.#heap;
|
|
1109
|
+
heap.push(record);
|
|
1110
|
+
let i = heap.length - 1;
|
|
1111
|
+
while (i > 0) {
|
|
1112
|
+
const parent = i - 1 >> 1;
|
|
1113
|
+
if (heap[parent].deadline <= heap[i].deadline)
|
|
1114
|
+
break;
|
|
1115
|
+
[heap[parent], heap[i]] = [heap[i], heap[parent]];
|
|
1116
|
+
i = parent;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
#heapPop() {
|
|
1120
|
+
const heap = this.#heap;
|
|
1121
|
+
const top = heap[0];
|
|
1122
|
+
const last = heap.pop();
|
|
1123
|
+
if (top === undefined || heap.length === 0)
|
|
1124
|
+
return top;
|
|
1125
|
+
heap[0] = last;
|
|
1126
|
+
for (let i = 0;; ) {
|
|
1127
|
+
const left = 2 * i + 1;
|
|
1128
|
+
const right = left + 1;
|
|
1129
|
+
let smallest = i;
|
|
1130
|
+
if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
|
|
1131
|
+
smallest = left;
|
|
1132
|
+
if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
|
|
1133
|
+
smallest = right;
|
|
1134
|
+
if (smallest === i)
|
|
1135
|
+
break;
|
|
1136
|
+
[heap[smallest], heap[i]] = [heap[i], heap[smallest]];
|
|
1137
|
+
i = smallest;
|
|
1138
|
+
}
|
|
1139
|
+
return top;
|
|
1140
|
+
}
|
|
690
1141
|
first() {
|
|
691
1142
|
for (const value of this.values())
|
|
692
1143
|
return value;
|
|
@@ -911,11 +1362,40 @@ class Manager {
|
|
|
911
1362
|
has(id) {
|
|
912
1363
|
return this.cache.has(id);
|
|
913
1364
|
}
|
|
1365
|
+
#inflight = new Map;
|
|
1366
|
+
fetchOnce(id, load, store = (value) => {
|
|
1367
|
+
this.set(id, value);
|
|
1368
|
+
return value;
|
|
1369
|
+
}) {
|
|
1370
|
+
const pending = this.#inflight.get(id);
|
|
1371
|
+
if (pending)
|
|
1372
|
+
return pending.promise;
|
|
1373
|
+
const entry = {
|
|
1374
|
+
promise: new Promise((resolve) => resolve(load())),
|
|
1375
|
+
dirty: false
|
|
1376
|
+
};
|
|
1377
|
+
this.#inflight.set(id, entry);
|
|
1378
|
+
entry.promise = entry.promise.then((value) => {
|
|
1379
|
+
this.#inflight.delete(id);
|
|
1380
|
+
return entry.dirty ? this.get(id) ?? value : store(value);
|
|
1381
|
+
}, (error) => {
|
|
1382
|
+
this.#inflight.delete(id);
|
|
1383
|
+
throw error;
|
|
1384
|
+
});
|
|
1385
|
+
return entry.promise;
|
|
1386
|
+
}
|
|
1387
|
+
#markDirty(id) {
|
|
1388
|
+
const pending = this.#inflight.get(id);
|
|
1389
|
+
if (pending)
|
|
1390
|
+
pending.dirty = true;
|
|
1391
|
+
}
|
|
914
1392
|
set(id, value) {
|
|
915
|
-
this
|
|
1393
|
+
this.#markDirty(id);
|
|
1394
|
+
this.cache.setWithoutTTL(id, value);
|
|
916
1395
|
return this;
|
|
917
1396
|
}
|
|
918
1397
|
delete(id) {
|
|
1398
|
+
this.#markDirty(id);
|
|
919
1399
|
return this.cache.delete(id);
|
|
920
1400
|
}
|
|
921
1401
|
clear() {
|
|
@@ -951,16 +1431,20 @@ class ResourceManager extends Manager {
|
|
|
951
1431
|
async resolve(id) {
|
|
952
1432
|
return this.get(id) ?? this.fetch(id);
|
|
953
1433
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
this.set(id, resource);
|
|
957
|
-
return resource;
|
|
1434
|
+
fetch(id) {
|
|
1435
|
+
return this.fetchOnce(id, () => this.#fetcher(id));
|
|
958
1436
|
}
|
|
959
1437
|
async fetchMany(ids) {
|
|
960
1438
|
return Promise.all([...ids].map((id) => this.resolve(id)));
|
|
961
1439
|
}
|
|
962
1440
|
upsert(resource) {
|
|
963
1441
|
const key = this.#key(resource);
|
|
1442
|
+
const existing = this.get(key);
|
|
1443
|
+
if (existing !== undefined && existing !== resource && typeof existing === "object" && existing !== null) {
|
|
1444
|
+
Object.assign(existing, resource);
|
|
1445
|
+
this.set(key, existing);
|
|
1446
|
+
return existing;
|
|
1447
|
+
}
|
|
964
1448
|
this.set(key, resource);
|
|
965
1449
|
return resource;
|
|
966
1450
|
}
|
|
@@ -971,7 +1455,7 @@ class ResourceManager extends Manager {
|
|
|
971
1455
|
// packages/rest/package.json
|
|
972
1456
|
var package_default = {
|
|
973
1457
|
name: "@lunibee/rest",
|
|
974
|
-
version: "0.
|
|
1458
|
+
version: "0.2.0",
|
|
975
1459
|
type: "module",
|
|
976
1460
|
module: "./src/index.ts",
|
|
977
1461
|
types: "./src/index.ts",
|
|
@@ -1031,7 +1515,29 @@ class MemoryRateLimitStore {
|
|
|
1031
1515
|
}
|
|
1032
1516
|
|
|
1033
1517
|
// packages/rest/src/errors.ts
|
|
1518
|
+
function kindFromStatus(status) {
|
|
1519
|
+
if (status === 429)
|
|
1520
|
+
return "rateLimited";
|
|
1521
|
+
if (status === 401)
|
|
1522
|
+
return "authentication";
|
|
1523
|
+
if (status === 403)
|
|
1524
|
+
return "permission";
|
|
1525
|
+
if (status === 404)
|
|
1526
|
+
return "notFound";
|
|
1527
|
+
if (status === 400 || status === 422)
|
|
1528
|
+
return "validation";
|
|
1529
|
+
if (status >= 500)
|
|
1530
|
+
return "server";
|
|
1531
|
+
if (status === 0)
|
|
1532
|
+
return "network";
|
|
1533
|
+
return "client";
|
|
1534
|
+
}
|
|
1535
|
+
function redactPath(path) {
|
|
1536
|
+
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/, "$1:token");
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1034
1539
|
class RESTError extends Error {
|
|
1540
|
+
kind;
|
|
1035
1541
|
status;
|
|
1036
1542
|
code;
|
|
1037
1543
|
errors;
|
|
@@ -1041,14 +1547,18 @@ class RESTError extends Error {
|
|
|
1041
1547
|
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
1042
1548
|
this.name = "RESTError";
|
|
1043
1549
|
this.status = status;
|
|
1550
|
+
this.kind = options.kind ?? kindFromStatus(status);
|
|
1044
1551
|
this.code = code;
|
|
1045
1552
|
this.errors = errors;
|
|
1046
1553
|
this.method = options.method;
|
|
1047
|
-
this.path = options.path;
|
|
1554
|
+
this.path = options.path === undefined ? undefined : redactPath(options.path);
|
|
1555
|
+
}
|
|
1556
|
+
get retryable() {
|
|
1557
|
+
return this.kind === "rateLimited" || this.kind === "server" || this.kind === "network" || this.kind === "timeout";
|
|
1048
1558
|
}
|
|
1049
1559
|
}
|
|
1050
1560
|
function abortError(path, reason) {
|
|
1051
|
-
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason });
|
|
1561
|
+
return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason, kind: "aborted" });
|
|
1052
1562
|
}
|
|
1053
1563
|
async function sleep(delay, signal, path) {
|
|
1054
1564
|
if (delay <= 0)
|
|
@@ -1383,8 +1893,23 @@ var Routes = {
|
|
|
1383
1893
|
invite: (code) => `/invites/${encodeURIComponent(code)}`,
|
|
1384
1894
|
guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
|
|
1385
1895
|
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
|
|
1896
|
+
applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`,
|
|
1897
|
+
pollExpire: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/expire`,
|
|
1898
|
+
pollAnswerVoters: (channelId, messageId, answerId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/answers/${integer(answerId, "Answer ID")}`,
|
|
1899
|
+
guildSticker: (guildId, stickerId) => stickerId ? `/guilds/${snowflake(guildId, "Guild ID")}/stickers/${snowflake(stickerId, "Sticker ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/stickers`,
|
|
1900
|
+
sendSoundboardSound: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/send-soundboard-sound`,
|
|
1901
|
+
soundboardDefaultSounds: () => "/soundboard-default-sounds",
|
|
1902
|
+
guildSoundboardSound: (guildId, soundId) => soundId ? `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds/${snowflake(soundId, "Sound ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds`,
|
|
1903
|
+
applicationSkus: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/skus`,
|
|
1904
|
+
applicationEntitlement: (applicationId, entitlementId) => entitlementId ? `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/entitlements`,
|
|
1905
|
+
consumeEntitlement: (applicationId, entitlementId) => `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}/consume`,
|
|
1906
|
+
skuSubscription: (skuId, subscriptionId) => subscriptionId ? `/skus/${snowflake(skuId, "SKU ID")}/subscriptions/${snowflake(subscriptionId, "Subscription ID")}` : `/skus/${snowflake(skuId, "SKU ID")}/subscriptions`
|
|
1387
1907
|
};
|
|
1908
|
+
function integer(value, field) {
|
|
1909
|
+
if (!Number.isInteger(value) || value < 0)
|
|
1910
|
+
throw new TypeError(`${field} must be a non-negative integer.`);
|
|
1911
|
+
return String(value);
|
|
1912
|
+
}
|
|
1388
1913
|
function snowflake(value, field) {
|
|
1389
1914
|
if (!/^\d{1,20}$/.test(value))
|
|
1390
1915
|
throw new TypeError(`${field} must be a valid Discord snowflake.`);
|
|
@@ -1521,7 +2046,8 @@ class REST {
|
|
|
1521
2046
|
throw new RESTError(failure.message, 0, undefined, undefined, {
|
|
1522
2047
|
method,
|
|
1523
2048
|
path,
|
|
1524
|
-
cause: failure.cause ?? failure
|
|
2049
|
+
cause: failure.cause ?? failure,
|
|
2050
|
+
kind: failure.timedOut ? "timeout" : "network"
|
|
1525
2051
|
});
|
|
1526
2052
|
}
|
|
1527
2053
|
this.#emit(this.#hooks.onResponse, {
|
|
@@ -1620,6 +2146,9 @@ class REST {
|
|
|
1620
2146
|
#emit(hook, ctx) {
|
|
1621
2147
|
if (!hook)
|
|
1622
2148
|
return;
|
|
2149
|
+
const withPath = ctx;
|
|
2150
|
+
if (typeof withPath.path === "string")
|
|
2151
|
+
ctx = { ...ctx, path: redactPath(withPath.path) };
|
|
1623
2152
|
Promise.resolve().then(() => hook(ctx)).catch(() => {});
|
|
1624
2153
|
}
|
|
1625
2154
|
}
|
|
@@ -1696,6 +2225,7 @@ class Channel extends BaseStructure {
|
|
|
1696
2225
|
nsfw;
|
|
1697
2226
|
rateLimitPerUser;
|
|
1698
2227
|
position;
|
|
2228
|
+
permissionOverwrites;
|
|
1699
2229
|
#context;
|
|
1700
2230
|
constructor(data, context) {
|
|
1701
2231
|
super(data.id);
|
|
@@ -1709,6 +2239,7 @@ class Channel extends BaseStructure {
|
|
|
1709
2239
|
this.nsfw = data.nsfw;
|
|
1710
2240
|
this.rateLimitPerUser = data.rate_limit_per_user;
|
|
1711
2241
|
this.position = data.position;
|
|
2242
|
+
this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
|
|
1712
2243
|
this.#context = context;
|
|
1713
2244
|
}
|
|
1714
2245
|
sendMessage(options) {
|
|
@@ -1867,6 +2398,103 @@ class Guild extends BaseStructure {
|
|
|
1867
2398
|
}
|
|
1868
2399
|
}
|
|
1869
2400
|
// packages/structures/src/resources.ts
|
|
2401
|
+
function toDateOrNull(value) {
|
|
2402
|
+
if (!value)
|
|
2403
|
+
return null;
|
|
2404
|
+
const date = new Date(value);
|
|
2405
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
class GuildMember {
|
|
2409
|
+
user;
|
|
2410
|
+
guildId;
|
|
2411
|
+
nickname;
|
|
2412
|
+
roleIds;
|
|
2413
|
+
pending;
|
|
2414
|
+
joinedAt;
|
|
2415
|
+
permissions;
|
|
2416
|
+
avatarHash;
|
|
2417
|
+
premiumSince;
|
|
2418
|
+
timedOutUntil;
|
|
2419
|
+
flags;
|
|
2420
|
+
constructor(data) {
|
|
2421
|
+
this.user = new User(data.user);
|
|
2422
|
+
if (!/^\d{1,20}$/.test(data.guild_id))
|
|
2423
|
+
throw new TypeError("Member guild_id must be a valid snowflake.");
|
|
2424
|
+
this.guildId = data.guild_id;
|
|
2425
|
+
this.nickname = data.nick ?? null;
|
|
2426
|
+
this.roleIds = [...data.roles ?? []];
|
|
2427
|
+
this.pending = data.pending ?? false;
|
|
2428
|
+
this.joinedAt = data.joined_at ? new Date(data.joined_at) : undefined;
|
|
2429
|
+
if (this.joinedAt?.toString() === "Invalid Date")
|
|
2430
|
+
throw new RangeError("Member joined_at must be a valid date.");
|
|
2431
|
+
this.permissions = new PermissionsBitField(data.permissions ?? 0n);
|
|
2432
|
+
this.avatarHash = data.avatar ?? null;
|
|
2433
|
+
this.premiumSince = toDateOrNull(data.premium_since);
|
|
2434
|
+
this.timedOutUntil = toDateOrNull(data.communication_disabled_until);
|
|
2435
|
+
this.flags = data.flags ?? 0;
|
|
2436
|
+
}
|
|
2437
|
+
get displayName() {
|
|
2438
|
+
return this.nickname ?? this.user.displayName;
|
|
2439
|
+
}
|
|
2440
|
+
get isTimedOut() {
|
|
2441
|
+
return this.timedOutUntil !== null && this.timedOutUntil > new Date;
|
|
2442
|
+
}
|
|
2443
|
+
avatarURL(options = {}) {
|
|
2444
|
+
if (this.avatarHash)
|
|
2445
|
+
return cdnURL(`/guilds/${this.guildId}/users/${this.user.id}/avatars`, this.avatarHash, options);
|
|
2446
|
+
return this.user.avatarURL(options);
|
|
2447
|
+
}
|
|
2448
|
+
displayAvatarURL(options = {}) {
|
|
2449
|
+
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
|
|
2450
|
+
}
|
|
2451
|
+
toString() {
|
|
2452
|
+
return this.user.toString();
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
class Role extends BaseStructure {
|
|
2457
|
+
name;
|
|
2458
|
+
color;
|
|
2459
|
+
hoist;
|
|
2460
|
+
permissions;
|
|
2461
|
+
managed;
|
|
2462
|
+
mentionable;
|
|
2463
|
+
position;
|
|
2464
|
+
unicodeEmoji;
|
|
2465
|
+
iconHash;
|
|
2466
|
+
tags;
|
|
2467
|
+
constructor(data) {
|
|
2468
|
+
super(data.id);
|
|
2469
|
+
if (!data.name)
|
|
2470
|
+
throw new TypeError("Role name cannot be empty.");
|
|
2471
|
+
this.name = data.name;
|
|
2472
|
+
this.color = data.color ?? 0;
|
|
2473
|
+
this.hoist = data.hoist ?? false;
|
|
2474
|
+
this.permissions = new PermissionsBitField(data.permissions ?? 0n);
|
|
2475
|
+
this.managed = data.managed ?? false;
|
|
2476
|
+
this.mentionable = data.mentionable ?? false;
|
|
2477
|
+
this.position = data.position ?? 0;
|
|
2478
|
+
this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
2479
|
+
this.iconHash = data.icon ?? null;
|
|
2480
|
+
this.tags = data.tags ?? null;
|
|
2481
|
+
}
|
|
2482
|
+
get colorHex() {
|
|
2483
|
+
return `#${this.color.toString(16).padStart(6, "0").toUpperCase()}`;
|
|
2484
|
+
}
|
|
2485
|
+
iconURL(options = {}) {
|
|
2486
|
+
if (!this.iconHash)
|
|
2487
|
+
return null;
|
|
2488
|
+
return cdnURL(`/role-icons/${this.id}`, this.iconHash, options);
|
|
2489
|
+
}
|
|
2490
|
+
isEveryone(guildId) {
|
|
2491
|
+
return this.id === guildId;
|
|
2492
|
+
}
|
|
2493
|
+
toString() {
|
|
2494
|
+
return `<@&${this.id}>`;
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
|
|
1870
2498
|
class TextChannel extends Channel {
|
|
1871
2499
|
constructor(data, context) {
|
|
1872
2500
|
super(data, context);
|
|
@@ -1875,6 +2503,38 @@ class TextChannel extends Channel {
|
|
|
1875
2503
|
return `<#${this.id}>`;
|
|
1876
2504
|
}
|
|
1877
2505
|
}
|
|
2506
|
+
class Emoji extends BaseStructure {
|
|
2507
|
+
name;
|
|
2508
|
+
roleIds;
|
|
2509
|
+
user;
|
|
2510
|
+
requireColons;
|
|
2511
|
+
managed;
|
|
2512
|
+
animated;
|
|
2513
|
+
available;
|
|
2514
|
+
constructor(data) {
|
|
2515
|
+
super(data.id ?? "0");
|
|
2516
|
+
if (data.id === null)
|
|
2517
|
+
this.id = "unicode";
|
|
2518
|
+
this.name = data.name;
|
|
2519
|
+
this.roleIds = data.roles ?? [];
|
|
2520
|
+
this.user = data.user ? new User(data.user) : null;
|
|
2521
|
+
this.requireColons = data.require_colons ?? false;
|
|
2522
|
+
this.managed = data.managed ?? false;
|
|
2523
|
+
this.animated = data.animated ?? false;
|
|
2524
|
+
this.available = data.available ?? true;
|
|
2525
|
+
}
|
|
2526
|
+
url(options = {}) {
|
|
2527
|
+
if (!this.id || this.id === "unicode")
|
|
2528
|
+
return null;
|
|
2529
|
+
const ext = options.extension ?? (this.animated ? "gif" : "png");
|
|
2530
|
+
const size = options.size ? `?size=${options.size}` : "";
|
|
2531
|
+
return `${CDN_BASE}/emojis/${this.id}.${ext}${size}`;
|
|
2532
|
+
}
|
|
2533
|
+
toString() {
|
|
2534
|
+
return this.id !== "unicode" ? `<${this.animated ? "a" : ""}:${this.name}:${this.id}>` : this.name ?? "";
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
|
|
1878
2538
|
class AutoModerationRule extends BaseStructure {
|
|
1879
2539
|
guildId;
|
|
1880
2540
|
name;
|
|
@@ -2192,6 +2852,17 @@ var InteractionType = {
|
|
|
2192
2852
|
ApplicationCommandAutocomplete: 4,
|
|
2193
2853
|
ModalSubmit: 5
|
|
2194
2854
|
};
|
|
2855
|
+
var EPHEMERAL = 64;
|
|
2856
|
+
var TOKEN_LIFETIME_MS = 15 * 60000;
|
|
2857
|
+
var DISCORD_EPOCH = 1420070400000n;
|
|
2858
|
+
function toMessageData(options) {
|
|
2859
|
+
if (typeof options === "string")
|
|
2860
|
+
return { content: options };
|
|
2861
|
+
const { ephemeral, ...data } = options;
|
|
2862
|
+
if (ephemeral)
|
|
2863
|
+
data.flags = (typeof data.flags === "number" ? data.flags : 0) | EPHEMERAL;
|
|
2864
|
+
return data;
|
|
2865
|
+
}
|
|
2195
2866
|
|
|
2196
2867
|
class InteractionResponse {
|
|
2197
2868
|
type;
|
|
@@ -2206,14 +2877,10 @@ class InteractionResponse {
|
|
|
2206
2877
|
return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
|
|
2207
2878
|
}
|
|
2208
2879
|
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);
|
|
2880
|
+
return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
|
|
2214
2881
|
}
|
|
2215
2882
|
static defer(ephemeral = false) {
|
|
2216
|
-
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags:
|
|
2883
|
+
return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
|
|
2217
2884
|
}
|
|
2218
2885
|
static pong() {
|
|
2219
2886
|
return new InteractionResponse(InteractionResponseType.Pong);
|
|
@@ -2231,6 +2898,7 @@ class Interaction {
|
|
|
2231
2898
|
replied = false;
|
|
2232
2899
|
deferred = false;
|
|
2233
2900
|
#client;
|
|
2901
|
+
#acknowledging = false;
|
|
2234
2902
|
constructor(client, data) {
|
|
2235
2903
|
if (!data.id || !data.token)
|
|
2236
2904
|
throw new TypeError("Interaction ID and token are required.");
|
|
@@ -2280,9 +2948,57 @@ class Interaction {
|
|
|
2280
2948
|
return [3, 5, 6, 7, 8].includes(this.#componentType());
|
|
2281
2949
|
}
|
|
2282
2950
|
assertUnacknowledged() {
|
|
2283
|
-
if (this.replied || this.deferred)
|
|
2951
|
+
if (this.replied || this.deferred || this.#acknowledging)
|
|
2284
2952
|
throw new Error("Interaction has already been acknowledged.");
|
|
2285
2953
|
}
|
|
2954
|
+
async acknowledge(response, state) {
|
|
2955
|
+
this.assertUnacknowledged();
|
|
2956
|
+
this.#acknowledging = true;
|
|
2957
|
+
try {
|
|
2958
|
+
const result = await this.postResponse(response);
|
|
2959
|
+
this[state] = true;
|
|
2960
|
+
return result;
|
|
2961
|
+
} finally {
|
|
2962
|
+
this.#acknowledging = false;
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
get user() {
|
|
2966
|
+
const raw = this.data.member?.user ?? this.data.user;
|
|
2967
|
+
return raw ? new User(raw) : null;
|
|
2968
|
+
}
|
|
2969
|
+
get member() {
|
|
2970
|
+
const raw = this.data.member;
|
|
2971
|
+
if (!raw || !this.guildId)
|
|
2972
|
+
return null;
|
|
2973
|
+
return new GuildMember({
|
|
2974
|
+
...raw,
|
|
2975
|
+
guild_id: this.guildId
|
|
2976
|
+
});
|
|
2977
|
+
}
|
|
2978
|
+
get createdTimestamp() {
|
|
2979
|
+
return Number((BigInt(this.id) >> 22n) + DISCORD_EPOCH);
|
|
2980
|
+
}
|
|
2981
|
+
get expiresAt() {
|
|
2982
|
+
return new Date(this.createdTimestamp + TOKEN_LIFETIME_MS);
|
|
2983
|
+
}
|
|
2984
|
+
get isExpired() {
|
|
2985
|
+
return Date.now() >= this.createdTimestamp + TOKEN_LIFETIME_MS;
|
|
2986
|
+
}
|
|
2987
|
+
#webhookMessage(method, messageId, data) {
|
|
2988
|
+
if (!this.#client.interactionWebhookMessage)
|
|
2989
|
+
return Promise.reject(new Error("This interaction client does not support webhook message access."));
|
|
2990
|
+
return this.#client.interactionWebhookMessage(method, this.applicationId, this.token, messageId, data);
|
|
2991
|
+
}
|
|
2992
|
+
fetchReply() {
|
|
2993
|
+
this.assertAcknowledged();
|
|
2994
|
+
return this.#webhookMessage("GET", "@original");
|
|
2995
|
+
}
|
|
2996
|
+
editFollowUp(messageId, options) {
|
|
2997
|
+
return this.#webhookMessage("PATCH", messageId, toMessageData(options));
|
|
2998
|
+
}
|
|
2999
|
+
async deleteFollowUp(messageId) {
|
|
3000
|
+
await this.#webhookMessage("DELETE", messageId);
|
|
3001
|
+
}
|
|
2286
3002
|
assertAcknowledged() {
|
|
2287
3003
|
if (!this.replied && !this.deferred)
|
|
2288
3004
|
throw new Error("Interaction has not been acknowledged.");
|
|
@@ -2291,41 +3007,27 @@ class Interaction {
|
|
|
2291
3007
|
return this.#client.postInteractionResponse(this.id, this.token, response);
|
|
2292
3008
|
}
|
|
2293
3009
|
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;
|
|
3010
|
+
return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
|
|
2299
3011
|
}
|
|
2300
3012
|
async deferReply(ephemeral = false) {
|
|
2301
|
-
this.
|
|
2302
|
-
await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.defer(ephemeral));
|
|
2303
|
-
this.deferred = true;
|
|
3013
|
+
await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
|
|
2304
3014
|
}
|
|
2305
3015
|
editReply(options) {
|
|
2306
3016
|
this.assertAcknowledged();
|
|
2307
|
-
return this.#client.editInteractionReply(this.token, options);
|
|
3017
|
+
return this.#client.editInteractionReply(this.token, toMessageData(options));
|
|
2308
3018
|
}
|
|
2309
3019
|
deleteReply() {
|
|
2310
3020
|
this.assertAcknowledged();
|
|
2311
3021
|
return this.#client.deleteInteractionReply(this.token);
|
|
2312
3022
|
}
|
|
2313
3023
|
followUp(options) {
|
|
2314
|
-
|
|
2315
|
-
return this.#client.followUpInteraction(this.token, payload);
|
|
3024
|
+
return this.#client.followUpInteraction(this.token, toMessageData(options));
|
|
2316
3025
|
}
|
|
2317
3026
|
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;
|
|
3027
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2323
3028
|
}
|
|
2324
3029
|
async showModal(modal) {
|
|
2325
|
-
this.
|
|
2326
|
-
const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.Modal, modal));
|
|
2327
|
-
this.replied = true;
|
|
2328
|
-
return result;
|
|
3030
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, modal), "replied");
|
|
2329
3031
|
}
|
|
2330
3032
|
}
|
|
2331
3033
|
|
|
@@ -2353,16 +3055,10 @@ class ComponentInteraction extends Interaction {
|
|
|
2353
3055
|
return this.data?.data?.values ?? [];
|
|
2354
3056
|
}
|
|
2355
3057
|
async deferUpdate() {
|
|
2356
|
-
this.
|
|
2357
|
-
await this.postResponse(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate));
|
|
2358
|
-
this.deferred = true;
|
|
3058
|
+
await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
|
|
2359
3059
|
}
|
|
2360
3060
|
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;
|
|
3061
|
+
return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
|
|
2366
3062
|
}
|
|
2367
3063
|
}
|
|
2368
3064
|
|
|
@@ -2405,8 +3101,7 @@ class AutocompleteInteraction extends Interaction {
|
|
|
2405
3101
|
if (!Array.isArray(choices))
|
|
2406
3102
|
throw new TypeError("Autocomplete choices must be an array.");
|
|
2407
3103
|
const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
|
|
2408
|
-
await this.
|
|
2409
|
-
this.replied = true;
|
|
3104
|
+
await this.acknowledge(response, "replied");
|
|
2410
3105
|
}
|
|
2411
3106
|
}
|
|
2412
3107
|
function findFocused(options) {
|
|
@@ -2593,16 +3288,22 @@ class Message extends BaseStructure {
|
|
|
2593
3288
|
|
|
2594
3289
|
// packages/managers/src/message.ts
|
|
2595
3290
|
class MessageManager {
|
|
2596
|
-
cache
|
|
3291
|
+
cache;
|
|
3292
|
+
#caching;
|
|
2597
3293
|
#rest;
|
|
2598
3294
|
#context;
|
|
2599
3295
|
#channelId;
|
|
2600
|
-
constructor(rest, context, channelId) {
|
|
3296
|
+
constructor(rest, context, channelId, cache) {
|
|
2601
3297
|
if (!channelId)
|
|
2602
3298
|
throw new TypeError("Channel ID is required.");
|
|
2603
3299
|
this.#rest = rest;
|
|
2604
3300
|
this.#context = context;
|
|
2605
3301
|
this.#channelId = channelId;
|
|
3302
|
+
this.#caching = cache !== undefined;
|
|
3303
|
+
this.cache = new Collection(null, {
|
|
3304
|
+
ttl: cache?.ttl,
|
|
3305
|
+
maxSize: cache ? cache.maxSize ?? 100 : undefined
|
|
3306
|
+
});
|
|
2606
3307
|
}
|
|
2607
3308
|
async resolve(messageId) {
|
|
2608
3309
|
return this.cache.get(messageId) ?? this.fetch(messageId);
|
|
@@ -2619,13 +3320,14 @@ class MessageManager {
|
|
|
2619
3320
|
return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
|
|
2620
3321
|
}
|
|
2621
3322
|
upsert(data) {
|
|
2622
|
-
const existing = this.cache.
|
|
3323
|
+
const existing = this.cache.peek(data.id);
|
|
2623
3324
|
const message = new Message(data, this.#context);
|
|
2624
3325
|
if (existing) {
|
|
2625
3326
|
Object.assign(existing, message);
|
|
2626
3327
|
return existing;
|
|
2627
3328
|
}
|
|
2628
|
-
this
|
|
3329
|
+
if (this.#caching)
|
|
3330
|
+
this.cache.set(message.id, message);
|
|
2629
3331
|
return message;
|
|
2630
3332
|
}
|
|
2631
3333
|
delete(messageId) {
|
|
@@ -2679,8 +3381,295 @@ class UserManager extends ResourceManager {
|
|
|
2679
3381
|
});
|
|
2680
3382
|
}
|
|
2681
3383
|
}
|
|
3384
|
+
// packages/managers/src/emoji.ts
|
|
3385
|
+
class EmojiManager extends Manager {
|
|
3386
|
+
#rest;
|
|
3387
|
+
#guildId;
|
|
3388
|
+
constructor(rest, guildId) {
|
|
3389
|
+
super();
|
|
3390
|
+
this.#rest = rest;
|
|
3391
|
+
this.#guildId = guildId;
|
|
3392
|
+
}
|
|
3393
|
+
fetch(emojiId) {
|
|
3394
|
+
return this.fetchOnce(emojiId, async () => new Emoji(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId))), (emoji) => this.#merge(emojiId, emoji));
|
|
3395
|
+
}
|
|
3396
|
+
async fetchAll() {
|
|
3397
|
+
const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
|
|
3398
|
+
return data.map((item) => this.upsert(item));
|
|
3399
|
+
}
|
|
3400
|
+
async create(options) {
|
|
3401
|
+
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
|
|
3402
|
+
}
|
|
3403
|
+
async edit(emojiId, options) {
|
|
3404
|
+
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
|
|
3405
|
+
}
|
|
3406
|
+
async deleteEmoji(emojiId) {
|
|
3407
|
+
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
|
|
3408
|
+
this.delete(emojiId);
|
|
3409
|
+
}
|
|
3410
|
+
upsert(data) {
|
|
3411
|
+
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
3412
|
+
return this.#merge(key, new Emoji(data));
|
|
3413
|
+
}
|
|
3414
|
+
#merge(key, emoji) {
|
|
3415
|
+
const existing = this.get(key);
|
|
3416
|
+
if (existing) {
|
|
3417
|
+
Object.assign(existing, emoji);
|
|
3418
|
+
return existing;
|
|
3419
|
+
}
|
|
3420
|
+
this.set(key, emoji);
|
|
3421
|
+
return emoji;
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
|
|
3425
|
+
// packages/managers/src/advanced.ts
|
|
3426
|
+
function withQuery(path, query) {
|
|
3427
|
+
const params = new URLSearchParams;
|
|
3428
|
+
for (const [key, value] of Object.entries(query))
|
|
3429
|
+
if (value !== undefined)
|
|
3430
|
+
params.set(key, String(value));
|
|
3431
|
+
const suffix = params.toString();
|
|
3432
|
+
return suffix ? `${path}?${suffix}` : path;
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3435
|
+
class GuildStickerManager extends Manager {
|
|
3436
|
+
#rest;
|
|
3437
|
+
guildId;
|
|
3438
|
+
constructor(rest, guildId) {
|
|
3439
|
+
super();
|
|
3440
|
+
this.#rest = rest;
|
|
3441
|
+
this.guildId = guildId;
|
|
3442
|
+
}
|
|
3443
|
+
#store(sticker) {
|
|
3444
|
+
this.set(sticker.id, sticker);
|
|
3445
|
+
return sticker;
|
|
3446
|
+
}
|
|
3447
|
+
async fetchAll() {
|
|
3448
|
+
const stickers = await this.#rest.get(Routes.guildSticker(this.guildId));
|
|
3449
|
+
this.clear();
|
|
3450
|
+
return stickers.map((sticker) => this.#store(sticker));
|
|
3451
|
+
}
|
|
3452
|
+
async fetch(stickerId) {
|
|
3453
|
+
return this.#store(await this.#rest.get(Routes.guildSticker(this.guildId, stickerId)));
|
|
3454
|
+
}
|
|
3455
|
+
async create(options) {
|
|
3456
|
+
const form = new FormData;
|
|
3457
|
+
form.set("name", options.name);
|
|
3458
|
+
form.set("description", options.description);
|
|
3459
|
+
form.set("tags", options.tags);
|
|
3460
|
+
form.set("file", options.file);
|
|
3461
|
+
return this.#store(await this.#rest.post(Routes.guildSticker(this.guildId), form, { reason: options.reason }));
|
|
3462
|
+
}
|
|
3463
|
+
async edit(stickerId, options) {
|
|
3464
|
+
const { reason, ...body } = options;
|
|
3465
|
+
return this.#store(await this.#rest.patch(Routes.guildSticker(this.guildId, stickerId), body, { reason }));
|
|
3466
|
+
}
|
|
3467
|
+
async remove(stickerId, reason) {
|
|
3468
|
+
await this.#rest.delete(Routes.guildSticker(this.guildId, stickerId), {
|
|
3469
|
+
reason
|
|
3470
|
+
});
|
|
3471
|
+
this.delete(stickerId);
|
|
3472
|
+
}
|
|
3473
|
+
sync(stickers) {
|
|
3474
|
+
this.clear();
|
|
3475
|
+
for (const sticker of stickers)
|
|
3476
|
+
this.#store(sticker);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
class GuildSoundboardManager extends Manager {
|
|
3481
|
+
#rest;
|
|
3482
|
+
guildId;
|
|
3483
|
+
constructor(rest, guildId) {
|
|
3484
|
+
super();
|
|
3485
|
+
this.#rest = rest;
|
|
3486
|
+
this.guildId = guildId;
|
|
3487
|
+
}
|
|
3488
|
+
#store(sound) {
|
|
3489
|
+
this.set(sound.sound_id, sound);
|
|
3490
|
+
return sound;
|
|
3491
|
+
}
|
|
3492
|
+
async fetchAll() {
|
|
3493
|
+
const { items } = await this.#rest.get(Routes.guildSoundboardSound(this.guildId));
|
|
3494
|
+
this.clear();
|
|
3495
|
+
return items.map((sound) => this.#store(sound));
|
|
3496
|
+
}
|
|
3497
|
+
async fetch(soundId) {
|
|
3498
|
+
return this.#store(await this.#rest.get(Routes.guildSoundboardSound(this.guildId, soundId)));
|
|
3499
|
+
}
|
|
3500
|
+
async create(options) {
|
|
3501
|
+
if (options.volume !== undefined && (options.volume < 0 || options.volume > 1))
|
|
3502
|
+
throw new RangeError("Soundboard volume must be between 0 and 1.");
|
|
3503
|
+
return this.#store(await this.#rest.post(Routes.guildSoundboardSound(this.guildId), {
|
|
3504
|
+
name: options.name,
|
|
3505
|
+
sound: options.sound,
|
|
3506
|
+
volume: options.volume,
|
|
3507
|
+
emoji_id: options.emojiId,
|
|
3508
|
+
emoji_name: options.emojiName
|
|
3509
|
+
}, { reason: options.reason }));
|
|
3510
|
+
}
|
|
3511
|
+
async edit(soundId, options) {
|
|
3512
|
+
return this.#store(await this.#rest.patch(Routes.guildSoundboardSound(this.guildId, soundId), {
|
|
3513
|
+
name: options.name,
|
|
3514
|
+
volume: options.volume,
|
|
3515
|
+
emoji_id: options.emojiId,
|
|
3516
|
+
emoji_name: options.emojiName
|
|
3517
|
+
}, { reason: options.reason }));
|
|
3518
|
+
}
|
|
3519
|
+
async remove(soundId, reason) {
|
|
3520
|
+
await this.#rest.delete(Routes.guildSoundboardSound(this.guildId, soundId), { reason });
|
|
3521
|
+
this.delete(soundId);
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
class MonetizationManager extends Manager {
|
|
3526
|
+
#rest;
|
|
3527
|
+
applicationId;
|
|
3528
|
+
constructor(rest, applicationId) {
|
|
3529
|
+
super();
|
|
3530
|
+
this.#rest = rest;
|
|
3531
|
+
this.applicationId = applicationId;
|
|
3532
|
+
}
|
|
3533
|
+
fetchSkus() {
|
|
3534
|
+
return this.#rest.get(Routes.applicationSkus(this.applicationId));
|
|
3535
|
+
}
|
|
3536
|
+
async fetchEntitlements(query = {}) {
|
|
3537
|
+
if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 100))
|
|
3538
|
+
throw new RangeError("Entitlement limit must be 1-100.");
|
|
3539
|
+
const entitlements = await this.#rest.get(withQuery(Routes.applicationEntitlement(this.applicationId), {
|
|
3540
|
+
user_id: query.userId,
|
|
3541
|
+
sku_ids: query.skuIds?.join(","),
|
|
3542
|
+
guild_id: query.guildId,
|
|
3543
|
+
before: query.before,
|
|
3544
|
+
after: query.after,
|
|
3545
|
+
limit: query.limit,
|
|
3546
|
+
exclude_ended: query.excludeEnded,
|
|
3547
|
+
exclude_deleted: query.excludeDeleted
|
|
3548
|
+
}));
|
|
3549
|
+
for (const entitlement of entitlements)
|
|
3550
|
+
this.set(entitlement.id, entitlement);
|
|
3551
|
+
return entitlements;
|
|
3552
|
+
}
|
|
3553
|
+
async fetch(entitlementId) {
|
|
3554
|
+
const entitlement = await this.#rest.get(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
3555
|
+
this.set(entitlement.id, entitlement);
|
|
3556
|
+
return entitlement;
|
|
3557
|
+
}
|
|
3558
|
+
async consume(entitlementId) {
|
|
3559
|
+
await this.#rest.post(Routes.consumeEntitlement(this.applicationId, entitlementId));
|
|
3560
|
+
const cached = this.get(entitlementId);
|
|
3561
|
+
if (cached)
|
|
3562
|
+
cached.consumed = true;
|
|
3563
|
+
}
|
|
3564
|
+
async createTestEntitlement(options) {
|
|
3565
|
+
const entitlement = await this.#rest.post(Routes.applicationEntitlement(this.applicationId), {
|
|
3566
|
+
sku_id: options.skuId,
|
|
3567
|
+
owner_id: options.ownerId,
|
|
3568
|
+
owner_type: options.ownerType
|
|
3569
|
+
});
|
|
3570
|
+
this.set(entitlement.id, entitlement);
|
|
3571
|
+
return entitlement;
|
|
3572
|
+
}
|
|
3573
|
+
async deleteTestEntitlement(entitlementId) {
|
|
3574
|
+
await this.#rest.delete(Routes.applicationEntitlement(this.applicationId, entitlementId));
|
|
3575
|
+
this.delete(entitlementId);
|
|
3576
|
+
}
|
|
3577
|
+
fetchSubscriptions(skuId, query = {}) {
|
|
3578
|
+
return this.#rest.get(withQuery(Routes.skuSubscription(skuId), {
|
|
3579
|
+
user_id: query.userId,
|
|
3580
|
+
before: query.before,
|
|
3581
|
+
after: query.after,
|
|
3582
|
+
limit: query.limit
|
|
3583
|
+
}));
|
|
3584
|
+
}
|
|
3585
|
+
fetchSubscription(skuId, subscriptionId) {
|
|
3586
|
+
return this.#rest.get(Routes.skuSubscription(skuId, subscriptionId));
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
// packages/managers/src/member.ts
|
|
3591
|
+
class GuildMemberManager extends ResourceManager {
|
|
3592
|
+
#rest;
|
|
3593
|
+
guildId;
|
|
3594
|
+
constructor(guildId, rest) {
|
|
3595
|
+
super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId })), (member) => member.user.id);
|
|
3596
|
+
this.guildId = guildId;
|
|
3597
|
+
this.#rest = rest;
|
|
3598
|
+
}
|
|
3599
|
+
async kick(userId) {
|
|
3600
|
+
await this.#rest.delete(Routes.guildMember(this.guildId, userId));
|
|
3601
|
+
this.delete(userId);
|
|
3602
|
+
}
|
|
3603
|
+
async ban(userId, options = {}) {
|
|
3604
|
+
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
3605
|
+
this.delete(userId);
|
|
3606
|
+
}
|
|
3607
|
+
async unban(userId) {
|
|
3608
|
+
await this.#rest.delete(Routes.guildBan(this.guildId, userId));
|
|
3609
|
+
}
|
|
3610
|
+
async edit(userId, options) {
|
|
3611
|
+
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options);
|
|
3612
|
+
const member = new GuildMember({ ...data, guild_id: this.guildId });
|
|
3613
|
+
this.set(member.user.id, member);
|
|
3614
|
+
return member;
|
|
3615
|
+
}
|
|
3616
|
+
async addRole(userId, roleId) {
|
|
3617
|
+
await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
3618
|
+
}
|
|
3619
|
+
async removeRole(userId, roleId) {
|
|
3620
|
+
await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId));
|
|
3621
|
+
}
|
|
3622
|
+
async timeout(userId, milliseconds) {
|
|
3623
|
+
const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
|
|
3624
|
+
return this.edit(userId, { communication_disabled_until: timeoutDate });
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
// packages/managers/src/role.ts
|
|
3629
|
+
class RoleManager extends ResourceManager {
|
|
3630
|
+
#rest;
|
|
3631
|
+
guildId;
|
|
3632
|
+
constructor(guildId, rest) {
|
|
3633
|
+
super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
|
|
3634
|
+
this.guildId = guildId;
|
|
3635
|
+
this.#rest = rest;
|
|
3636
|
+
}
|
|
3637
|
+
async fetchAll() {
|
|
3638
|
+
const data = await this.#rest.get(Routes.guildRoles(this.guildId));
|
|
3639
|
+
return data.map((item) => {
|
|
3640
|
+
const role = new Role(item);
|
|
3641
|
+
this.set(role.id, role);
|
|
3642
|
+
return role;
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
async create(options) {
|
|
3646
|
+
const { reason, ...payload } = options;
|
|
3647
|
+
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
3648
|
+
...payload,
|
|
3649
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3650
|
+
});
|
|
3651
|
+
const role = new Role(data);
|
|
3652
|
+
this.set(role.id, role);
|
|
3653
|
+
return role;
|
|
3654
|
+
}
|
|
3655
|
+
async edit(roleId, options) {
|
|
3656
|
+
const { reason, ...payload } = options;
|
|
3657
|
+
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
3658
|
+
...payload,
|
|
3659
|
+
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3660
|
+
});
|
|
3661
|
+
const role = new Role(data);
|
|
3662
|
+
this.set(role.id, role);
|
|
3663
|
+
return role;
|
|
3664
|
+
}
|
|
3665
|
+
async deleteRole(roleId) {
|
|
3666
|
+
await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
|
|
3667
|
+
this.delete(roleId);
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
|
|
2682
3671
|
// packages/managers/src/guild-resources.ts
|
|
2683
|
-
function
|
|
3672
|
+
function withQuery2(path, params) {
|
|
2684
3673
|
const query = new URLSearchParams;
|
|
2685
3674
|
for (const [key, value] of Object.entries(params))
|
|
2686
3675
|
if (value !== undefined)
|
|
@@ -2704,7 +3693,7 @@ class GuildBanManager extends Manager {
|
|
|
2704
3693
|
}
|
|
2705
3694
|
async fetchAll(options = {}) {
|
|
2706
3695
|
const limit = options.limit === undefined ? undefined : Math.min(1000, Math.max(1, options.limit));
|
|
2707
|
-
const bans = await this.#rest.get(
|
|
3696
|
+
const bans = await this.#rest.get(withQuery2(Routes.guildBans(this.guildId), {
|
|
2708
3697
|
limit,
|
|
2709
3698
|
before: options.before,
|
|
2710
3699
|
after: options.after
|
|
@@ -2737,12 +3726,12 @@ class GuildScheduledEventManager extends Manager {
|
|
|
2737
3726
|
return event;
|
|
2738
3727
|
}
|
|
2739
3728
|
async fetch(eventId, options = {}) {
|
|
2740
|
-
return this.#store(await this.#rest.get(
|
|
3729
|
+
return this.#store(await this.#rest.get(withQuery2(Routes.guildScheduledEvent(this.guildId, eventId), {
|
|
2741
3730
|
with_user_count: options.withUserCount
|
|
2742
3731
|
})));
|
|
2743
3732
|
}
|
|
2744
3733
|
async fetchAll(options = {}) {
|
|
2745
|
-
const events = await this.#rest.get(
|
|
3734
|
+
const events = await this.#rest.get(withQuery2(Routes.guildScheduledEvents(this.guildId), {
|
|
2746
3735
|
with_user_count: options.withUserCount
|
|
2747
3736
|
}));
|
|
2748
3737
|
return events.map((event) => this.#store(event));
|
|
@@ -2759,7 +3748,7 @@ class GuildScheduledEventManager extends Manager {
|
|
|
2759
3748
|
}
|
|
2760
3749
|
async fetchSubscribers(eventId, options = {}) {
|
|
2761
3750
|
const limit = options.limit === undefined ? undefined : Math.min(100, Math.max(1, options.limit));
|
|
2762
|
-
return this.#rest.get(
|
|
3751
|
+
return this.#rest.get(withQuery2(Routes.guildScheduledEventUsers(this.guildId, eventId), {
|
|
2763
3752
|
limit,
|
|
2764
3753
|
with_member: options.withMember,
|
|
2765
3754
|
before: options.before,
|
|
@@ -2821,7 +3810,7 @@ class PermissionOverwriteManager {
|
|
|
2821
3810
|
}
|
|
2822
3811
|
|
|
2823
3812
|
// packages/managers/src/guild.ts
|
|
2824
|
-
function
|
|
3813
|
+
function withQuery3(path, params) {
|
|
2825
3814
|
const suffix = params.toString();
|
|
2826
3815
|
return suffix ? `${path}?${suffix}` : path;
|
|
2827
3816
|
}
|
|
@@ -2830,6 +3819,20 @@ class GuildManager extends ResourceManager {
|
|
|
2830
3819
|
#rest;
|
|
2831
3820
|
#bans = new Map;
|
|
2832
3821
|
#scheduledEvents = new Map;
|
|
3822
|
+
#members = new Map;
|
|
3823
|
+
#roles = new Map;
|
|
3824
|
+
#emojis = new Map;
|
|
3825
|
+
#stickers = new Map;
|
|
3826
|
+
#soundboard = new Map;
|
|
3827
|
+
#voiceStates = new Map;
|
|
3828
|
+
#autoModerationRules = new Map;
|
|
3829
|
+
#invites = new Map;
|
|
3830
|
+
#perGuild(map, guildId, create) {
|
|
3831
|
+
let manager = map.get(guildId);
|
|
3832
|
+
if (!manager)
|
|
3833
|
+
map.set(guildId, manager = create());
|
|
3834
|
+
return manager;
|
|
3835
|
+
}
|
|
2833
3836
|
constructor(rest) {
|
|
2834
3837
|
super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
|
|
2835
3838
|
this.#rest = rest;
|
|
@@ -2846,6 +3849,68 @@ class GuildManager extends ResourceManager {
|
|
|
2846
3849
|
this.#scheduledEvents.set(guildId, manager = new GuildScheduledEventManager(this.#rest, guildId));
|
|
2847
3850
|
return manager;
|
|
2848
3851
|
}
|
|
3852
|
+
members(guildId) {
|
|
3853
|
+
let manager = this.#members.get(guildId);
|
|
3854
|
+
if (!manager)
|
|
3855
|
+
this.#members.set(guildId, manager = new GuildMemberManager(guildId, this.#rest));
|
|
3856
|
+
return manager;
|
|
3857
|
+
}
|
|
3858
|
+
roles(guildId) {
|
|
3859
|
+
let manager = this.#roles.get(guildId);
|
|
3860
|
+
if (!manager)
|
|
3861
|
+
this.#roles.set(guildId, manager = new RoleManager(guildId, this.#rest));
|
|
3862
|
+
return manager;
|
|
3863
|
+
}
|
|
3864
|
+
emojis(guildId) {
|
|
3865
|
+
let manager = this.#emojis.get(guildId);
|
|
3866
|
+
if (!manager)
|
|
3867
|
+
this.#emojis.set(guildId, manager = new EmojiManager(this.#rest, guildId));
|
|
3868
|
+
return manager;
|
|
3869
|
+
}
|
|
3870
|
+
stickers(guildId) {
|
|
3871
|
+
let manager = this.#stickers.get(guildId);
|
|
3872
|
+
if (!manager)
|
|
3873
|
+
this.#stickers.set(guildId, manager = new GuildStickerManager(this.#rest, guildId));
|
|
3874
|
+
return manager;
|
|
3875
|
+
}
|
|
3876
|
+
soundboard(guildId) {
|
|
3877
|
+
let manager = this.#soundboard.get(guildId);
|
|
3878
|
+
if (!manager)
|
|
3879
|
+
this.#soundboard.set(guildId, manager = new GuildSoundboardManager(this.#rest, guildId));
|
|
3880
|
+
return manager;
|
|
3881
|
+
}
|
|
3882
|
+
voiceStates(guildId) {
|
|
3883
|
+
return this.#perGuild(this.#voiceStates, guildId, () => new Manager);
|
|
3884
|
+
}
|
|
3885
|
+
autoModerationRules(guildId) {
|
|
3886
|
+
return this.#perGuild(this.#autoModerationRules, guildId, () => new Manager);
|
|
3887
|
+
}
|
|
3888
|
+
invites(guildId) {
|
|
3889
|
+
return this.#perGuild(this.#invites, guildId, () => new Manager);
|
|
3890
|
+
}
|
|
3891
|
+
patch(data) {
|
|
3892
|
+
const guild = new Guild(data);
|
|
3893
|
+
const existing = this.get(guild.id);
|
|
3894
|
+
if (!existing)
|
|
3895
|
+
return this.upsert(guild);
|
|
3896
|
+
for (const [key, value] of Object.entries(guild))
|
|
3897
|
+
if (value !== undefined)
|
|
3898
|
+
existing[key] = value;
|
|
3899
|
+
return existing;
|
|
3900
|
+
}
|
|
3901
|
+
delete(id) {
|
|
3902
|
+
this.#bans.delete(id);
|
|
3903
|
+
this.#scheduledEvents.delete(id);
|
|
3904
|
+
this.#members.delete(id);
|
|
3905
|
+
this.#roles.delete(id);
|
|
3906
|
+
this.#emojis.delete(id);
|
|
3907
|
+
this.#stickers.delete(id);
|
|
3908
|
+
this.#soundboard.delete(id);
|
|
3909
|
+
this.#voiceStates.delete(id);
|
|
3910
|
+
this.#autoModerationRules.delete(id);
|
|
3911
|
+
this.#invites.delete(id);
|
|
3912
|
+
return super.delete(id);
|
|
3913
|
+
}
|
|
2849
3914
|
async create(options) {
|
|
2850
3915
|
const data = await this.#rest.post("/guilds", options);
|
|
2851
3916
|
return this.upsert(new Guild(data));
|
|
@@ -2881,7 +3946,7 @@ class GuildManager extends ResourceManager {
|
|
|
2881
3946
|
params.set("after", options.after);
|
|
2882
3947
|
if (options.limit !== undefined)
|
|
2883
3948
|
params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
|
|
2884
|
-
return this.#rest.get(
|
|
3949
|
+
return this.#rest.get(withQuery3(Routes.guildAuditLog(guildId), params));
|
|
2885
3950
|
}
|
|
2886
3951
|
async fetchMembers(guildId, options = {}) {
|
|
2887
3952
|
const params = new URLSearchParams;
|
|
@@ -2889,7 +3954,7 @@ class GuildManager extends ResourceManager {
|
|
|
2889
3954
|
params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
|
|
2890
3955
|
if (options.after)
|
|
2891
3956
|
params.set("after", options.after);
|
|
2892
|
-
return this.#rest.get(
|
|
3957
|
+
return this.#rest.get(withQuery3(Routes.guildMembers(guildId), params));
|
|
2893
3958
|
}
|
|
2894
3959
|
async fetchAutoModerationRules(guildId) {
|
|
2895
3960
|
const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
|
|
@@ -2952,13 +4017,20 @@ class ApplicationCommandManager {
|
|
|
2952
4017
|
}
|
|
2953
4018
|
|
|
2954
4019
|
// packages/managers/src/index.ts
|
|
4020
|
+
var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
|
|
4021
|
+
function snowflakeTime(id) {
|
|
4022
|
+
return Number((BigInt(id) >> 22n) + 1420070400000n);
|
|
4023
|
+
}
|
|
4024
|
+
|
|
2955
4025
|
class ChannelManager extends Manager {
|
|
2956
4026
|
#rest;
|
|
2957
4027
|
#context;
|
|
2958
4028
|
#messageManagers = new Map;
|
|
2959
|
-
|
|
4029
|
+
#messageCache;
|
|
4030
|
+
constructor(rest, options = {}) {
|
|
2960
4031
|
super();
|
|
2961
4032
|
this.#rest = rest;
|
|
4033
|
+
this.#messageCache = options.messageCache;
|
|
2962
4034
|
this.#context = {
|
|
2963
4035
|
sendMessage: (channelId, options) => this.send(channelId, options),
|
|
2964
4036
|
editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
|
|
@@ -2977,7 +4049,7 @@ class ChannelManager extends Manager {
|
|
|
2977
4049
|
messages(channelId) {
|
|
2978
4050
|
let manager = this.#messageManagers.get(channelId);
|
|
2979
4051
|
if (!manager) {
|
|
2980
|
-
manager = new MessageManager(this.#rest, this.#context, channelId);
|
|
4052
|
+
manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
|
|
2981
4053
|
this.#messageManagers.set(channelId, manager);
|
|
2982
4054
|
}
|
|
2983
4055
|
return manager;
|
|
@@ -2988,16 +4060,18 @@ class ChannelManager extends Manager {
|
|
|
2988
4060
|
threads(channelId) {
|
|
2989
4061
|
return new ThreadManager(this.#rest, this.#context, channelId);
|
|
2990
4062
|
}
|
|
2991
|
-
|
|
2992
|
-
return this.
|
|
4063
|
+
fetch(channelId) {
|
|
4064
|
+
return this.fetchOnce(channelId, async () => createChannel(await this.#rest.get(Routes.channel(channelId)), this.#context), (channel) => this.#merge(channel));
|
|
2993
4065
|
}
|
|
2994
4066
|
async resolve(channelId) {
|
|
2995
4067
|
return this.get(channelId) ?? this.fetch(channelId);
|
|
2996
4068
|
}
|
|
2997
4069
|
upsert(data) {
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
4070
|
+
return this.#merge(createChannel(data, this.#context));
|
|
4071
|
+
}
|
|
4072
|
+
#merge(channel) {
|
|
4073
|
+
const existing = this.get(channel.id);
|
|
4074
|
+
if (existing && existing.type === channel.type) {
|
|
3001
4075
|
Object.assign(existing, channel);
|
|
3002
4076
|
return existing;
|
|
3003
4077
|
}
|
|
@@ -3007,6 +4081,37 @@ class ChannelManager extends Manager {
|
|
|
3007
4081
|
update(channel) {
|
|
3008
4082
|
return this.set(channel.id, channel);
|
|
3009
4083
|
}
|
|
4084
|
+
deleteGuildChannels(guildId) {
|
|
4085
|
+
let removed = 0;
|
|
4086
|
+
for (const channel of this.values())
|
|
4087
|
+
if (channel.guildId === guildId && this.delete(channel.id))
|
|
4088
|
+
removed++;
|
|
4089
|
+
return removed;
|
|
4090
|
+
}
|
|
4091
|
+
async endPoll(channelId, messageId) {
|
|
4092
|
+
return this.messages(channelId).upsert(await this.#rest.post(Routes.pollExpire(channelId, messageId)));
|
|
4093
|
+
}
|
|
4094
|
+
async fetchPollVoters(channelId, messageId, answerId, options = {}) {
|
|
4095
|
+
if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100))
|
|
4096
|
+
throw new RangeError("Poll voter limit must be 1-100.");
|
|
4097
|
+
const params = new URLSearchParams;
|
|
4098
|
+
if (options.after)
|
|
4099
|
+
params.set("after", options.after);
|
|
4100
|
+
if (options.limit !== undefined)
|
|
4101
|
+
params.set("limit", String(options.limit));
|
|
4102
|
+
const suffix = params.toString();
|
|
4103
|
+
const { users } = await this.#rest.get(`${Routes.pollAnswerVoters(channelId, messageId, answerId)}${suffix ? `?${suffix}` : ""}`);
|
|
4104
|
+
return users.map((user) => new User(user));
|
|
4105
|
+
}
|
|
4106
|
+
async sendSoundboardSound(channelId, options) {
|
|
4107
|
+
await this.#rest.post(Routes.sendSoundboardSound(channelId), {
|
|
4108
|
+
sound_id: options.soundId,
|
|
4109
|
+
source_guild_id: options.sourceGuildId
|
|
4110
|
+
});
|
|
4111
|
+
}
|
|
4112
|
+
cachedMessages(channelId) {
|
|
4113
|
+
return this.#messageManagers.get(channelId);
|
|
4114
|
+
}
|
|
3010
4115
|
async create(guildId, options) {
|
|
3011
4116
|
return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
|
|
3012
4117
|
}
|
|
@@ -3063,15 +4168,37 @@ class ChannelManager extends Manager {
|
|
|
3063
4168
|
return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
|
|
3064
4169
|
}
|
|
3065
4170
|
async bulkDeleteMessages(channelId, messageIds) {
|
|
3066
|
-
const ids = [...messageIds];
|
|
3067
|
-
if (ids.length <
|
|
3068
|
-
throw new RangeError("bulkDelete requires between
|
|
4171
|
+
const ids = [...new Set(messageIds)];
|
|
4172
|
+
if (ids.length < 1 || ids.length > 100)
|
|
4173
|
+
throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
|
|
4174
|
+
if (ids.length === 1)
|
|
4175
|
+
return this.deleteMessage(channelId, ids[0]);
|
|
4176
|
+
const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
|
|
4177
|
+
const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
|
|
4178
|
+
if (tooOld.length)
|
|
4179
|
+
throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
|
|
3069
4180
|
await this.#rest.post(Routes.channelBulkDelete(channelId), {
|
|
3070
4181
|
messages: ids
|
|
3071
4182
|
});
|
|
3072
4183
|
for (const id of ids)
|
|
3073
4184
|
this.messages(channelId).delete(id);
|
|
3074
4185
|
}
|
|
4186
|
+
async* iterateMessages(channelId, options = {}) {
|
|
4187
|
+
let before = options.before;
|
|
4188
|
+
let remaining = options.limit ?? Infinity;
|
|
4189
|
+
while (remaining > 0) {
|
|
4190
|
+
const page = await this.fetchMessages(channelId, {
|
|
4191
|
+
before,
|
|
4192
|
+
limit: Math.min(100, remaining)
|
|
4193
|
+
});
|
|
4194
|
+
for (const message of page)
|
|
4195
|
+
yield message;
|
|
4196
|
+
remaining -= page.length;
|
|
4197
|
+
if (page.length < 100)
|
|
4198
|
+
return;
|
|
4199
|
+
before = page.at(-1).id;
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
3075
4202
|
async addReaction(channelId, messageId, emoji) {
|
|
3076
4203
|
await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
|
|
3077
4204
|
}
|
|
@@ -3167,6 +4294,8 @@ class GatewaySession {
|
|
|
3167
4294
|
return false;
|
|
3168
4295
|
if (!Number.isInteger(sequence))
|
|
3169
4296
|
return false;
|
|
4297
|
+
if (this.#sequence !== null && sequence < this.#sequence)
|
|
4298
|
+
return false;
|
|
3170
4299
|
this.#sequence = sequence;
|
|
3171
4300
|
return true;
|
|
3172
4301
|
}
|
|
@@ -3265,8 +4394,11 @@ class GatewayHeartbeat {
|
|
|
3265
4394
|
this.#clearBeatTimers();
|
|
3266
4395
|
this.#interval = interval;
|
|
3267
4396
|
this.#acknowledged = true;
|
|
3268
|
-
this.#initialTimer = setTimeout(() =>
|
|
3269
|
-
|
|
4397
|
+
this.#initialTimer = setTimeout(() => {
|
|
4398
|
+
this.#initialTimer = undefined;
|
|
4399
|
+
this.sendHeartbeat();
|
|
4400
|
+
this.#timer = setInterval(() => this.sendHeartbeat(), interval);
|
|
4401
|
+
}, Math.random() * interval);
|
|
3270
4402
|
}
|
|
3271
4403
|
stop() {
|
|
3272
4404
|
this.#clearBeatTimers();
|
|
@@ -3292,6 +4424,8 @@ class GatewayHeartbeat {
|
|
|
3292
4424
|
}, this.#options.ackTimeout);
|
|
3293
4425
|
}
|
|
3294
4426
|
acknowledge() {
|
|
4427
|
+
if (this.#acknowledged)
|
|
4428
|
+
return;
|
|
3295
4429
|
this.#acknowledged = true;
|
|
3296
4430
|
this.#latency = this.#now() - this.#sentAt;
|
|
3297
4431
|
this.#clearAckTimer();
|
|
@@ -3860,6 +4994,7 @@ class SendBudget {
|
|
|
3860
4994
|
}
|
|
3861
4995
|
|
|
3862
4996
|
// packages/ws/src/index.ts
|
|
4997
|
+
var RESUMABLE_CLOSE_CODE = 4900;
|
|
3863
4998
|
var DEFAULT_GATEWAY_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
3864
4999
|
|
|
3865
5000
|
class Gateway {
|
|
@@ -3945,7 +5080,7 @@ class Gateway {
|
|
|
3945
5080
|
} else {
|
|
3946
5081
|
this.#emitError(new GatewayError(`Gateway heartbeat acknowledgement timed out after ${timeout.elapsedMs}ms.`));
|
|
3947
5082
|
}
|
|
3948
|
-
this.#transport.close(
|
|
5083
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, timeout.type === "zombie" ? "Zombie Gateway connection" : "Heartbeat timeout");
|
|
3949
5084
|
}
|
|
3950
5085
|
connect(url = DEFAULT_GATEWAY_URL) {
|
|
3951
5086
|
if (this.state === "CLOSED" /* Closed */)
|
|
@@ -4081,7 +5216,7 @@ class Gateway {
|
|
|
4081
5216
|
this.#emit("heartbeatAck", action.data);
|
|
4082
5217
|
return;
|
|
4083
5218
|
case "reconnect":
|
|
4084
|
-
this.#transport.close(
|
|
5219
|
+
this.#transport.close(RESUMABLE_CLOSE_CODE, "Server requested reconnect");
|
|
4085
5220
|
return;
|
|
4086
5221
|
case "invalid-session": {
|
|
4087
5222
|
if (!action.resumable)
|
|
@@ -4275,6 +5410,7 @@ class Client extends EventEmitter2 {
|
|
|
4275
5410
|
channels;
|
|
4276
5411
|
stageInstances;
|
|
4277
5412
|
application;
|
|
5413
|
+
monetization;
|
|
4278
5414
|
get ws() {
|
|
4279
5415
|
return this.#gateway;
|
|
4280
5416
|
}
|
|
@@ -4306,6 +5442,7 @@ class Client extends EventEmitter2 {
|
|
|
4306
5442
|
return this.#gateway.requestGuildMembers(data);
|
|
4307
5443
|
}
|
|
4308
5444
|
#gateway;
|
|
5445
|
+
#cache;
|
|
4309
5446
|
#resourceContext;
|
|
4310
5447
|
constructor(options) {
|
|
4311
5448
|
super();
|
|
@@ -4313,9 +5450,18 @@ class Client extends EventEmitter2 {
|
|
|
4313
5450
|
if (!options.token?.trim())
|
|
4314
5451
|
throw new TypeError("Client token is required.");
|
|
4315
5452
|
this.rest = new REST({ token: options.token, ...options.rest });
|
|
5453
|
+
this.#cache = {
|
|
5454
|
+
users: true,
|
|
5455
|
+
members: true,
|
|
5456
|
+
roles: true,
|
|
5457
|
+
emojis: true,
|
|
5458
|
+
...options.cache
|
|
5459
|
+
};
|
|
4316
5460
|
this.users = new UserManager(this.rest);
|
|
4317
5461
|
this.guilds = new GuildManager(this.rest);
|
|
4318
|
-
this.channels = new ChannelManager(this.rest
|
|
5462
|
+
this.channels = new ChannelManager(this.rest, {
|
|
5463
|
+
messageCache: options.messageCache
|
|
5464
|
+
});
|
|
4319
5465
|
this.stageInstances = new StageInstanceManager(this.rest);
|
|
4320
5466
|
const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
|
|
4321
5467
|
this.application = { commands: placeholderAppCommands };
|
|
@@ -4346,6 +5492,8 @@ class Client extends EventEmitter2 {
|
|
|
4346
5492
|
this.state = "ready";
|
|
4347
5493
|
const appId = ready.application?.id ?? this.user.id;
|
|
4348
5494
|
this.application.commands = new ApplicationCommandManager(this.rest, appId);
|
|
5495
|
+
if (this.monetization?.applicationId !== appId)
|
|
5496
|
+
this.monetization = new MonetizationManager(this.rest, appId);
|
|
4349
5497
|
this.emit("ready" /* Ready */, this.user);
|
|
4350
5498
|
});
|
|
4351
5499
|
this.#gateway.on("RESUMED", () => {
|
|
@@ -4363,18 +5511,39 @@ class Client extends EventEmitter2 {
|
|
|
4363
5511
|
});
|
|
4364
5512
|
this.#gateway.on("MESSAGE_CREATE", (data) => {
|
|
4365
5513
|
const message = new Message(data, this.#resourceContext);
|
|
4366
|
-
this
|
|
4367
|
-
this.
|
|
4368
|
-
this.emit("messageCreate" /* MessageCreate */,
|
|
5514
|
+
this.#observeMessage(message);
|
|
5515
|
+
const cached = this.options.messageCache ? this.channels.messages(message.channelId).upsert(data) : message;
|
|
5516
|
+
this.emit("messageCreate" /* MessageCreate */, cached);
|
|
4369
5517
|
});
|
|
4370
5518
|
this.#gateway.on("MESSAGE_UPDATE", (data) => {
|
|
4371
5519
|
const message = new Message(data, this.#resourceContext);
|
|
4372
|
-
this
|
|
4373
|
-
this.
|
|
4374
|
-
|
|
5520
|
+
this.#observeMessage(message);
|
|
5521
|
+
const messages = this.channels.cachedMessages(message.channelId);
|
|
5522
|
+
const previous = messages?.cache.peek(message.id);
|
|
5523
|
+
if (previous)
|
|
5524
|
+
messages.cache.set(message.id, message);
|
|
5525
|
+
this.emit("messageUpdate" /* MessageUpdate */, message, previous);
|
|
5526
|
+
});
|
|
5527
|
+
this.#gateway.on("MESSAGE_DELETE", (data) => {
|
|
5528
|
+
const payload = data;
|
|
5529
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
5530
|
+
const removed = messages?.cache.peek(payload.id);
|
|
5531
|
+
messages?.delete(payload.id);
|
|
5532
|
+
this.emit("messageDelete" /* MessageDelete */, payload, removed);
|
|
5533
|
+
});
|
|
5534
|
+
this.#gateway.on("MESSAGE_DELETE_BULK", (data) => {
|
|
5535
|
+
const payload = data;
|
|
5536
|
+
const messages = this.channels.cachedMessages(payload.channel_id);
|
|
5537
|
+
const removed = [];
|
|
5538
|
+
if (messages)
|
|
5539
|
+
for (const id of payload.ids) {
|
|
5540
|
+
const message = messages.cache.peek(id);
|
|
5541
|
+
if (message)
|
|
5542
|
+
removed.push(message);
|
|
5543
|
+
messages.delete(id);
|
|
5544
|
+
}
|
|
5545
|
+
this.emit("messageDeleteBulk" /* MessageDeleteBulk */, payload, removed);
|
|
4375
5546
|
});
|
|
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
5547
|
this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
|
|
4379
5548
|
this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
|
|
4380
5549
|
this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
|
|
@@ -4388,20 +5557,27 @@ class Client extends EventEmitter2 {
|
|
|
4388
5557
|
return;
|
|
4389
5558
|
}
|
|
4390
5559
|
const wasCached = this.guilds.has(payload.id);
|
|
4391
|
-
|
|
4392
|
-
|
|
5560
|
+
this.guilds.patch(payload);
|
|
5561
|
+
for (const role of payload.roles ?? [])
|
|
5562
|
+
this.#upsertRole(payload.id, role);
|
|
5563
|
+
if (this.#cache.emojis) {
|
|
5564
|
+
const emojis = this.guilds.emojis(payload.id);
|
|
5565
|
+
for (const emoji of payload.emojis ?? [])
|
|
5566
|
+
emojis.upsert(emoji);
|
|
5567
|
+
}
|
|
4393
5568
|
for (const member of payload.members ?? [])
|
|
4394
|
-
this
|
|
5569
|
+
this.#upsertMember(payload.id, member);
|
|
5570
|
+
for (const state of payload.voice_states ?? [])
|
|
5571
|
+
this.#storeVoiceState(payload.id, state);
|
|
4395
5572
|
for (const channelData of [
|
|
4396
5573
|
...payload.channels ?? [],
|
|
4397
5574
|
...payload.threads ?? []
|
|
4398
5575
|
])
|
|
4399
|
-
this.channels.
|
|
5576
|
+
this.channels.upsert({ ...channelData, guild_id: payload.id });
|
|
4400
5577
|
this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
|
|
4401
5578
|
});
|
|
4402
5579
|
this.#gateway.on("GUILD_UPDATE", (data) => {
|
|
4403
|
-
|
|
4404
|
-
this.guilds.update(guild);
|
|
5580
|
+
this.guilds.patch(data);
|
|
4405
5581
|
this.emit("guildUpdate" /* GuildUpdate */, data);
|
|
4406
5582
|
});
|
|
4407
5583
|
this.#gateway.on("GUILD_DELETE", (data) => {
|
|
@@ -4411,45 +5587,158 @@ class Client extends EventEmitter2 {
|
|
|
4411
5587
|
return;
|
|
4412
5588
|
}
|
|
4413
5589
|
this.guilds.delete(payload.id);
|
|
5590
|
+
this.channels.deleteGuildChannels(payload.id);
|
|
4414
5591
|
this.emit("guildDelete" /* GuildDelete */, payload);
|
|
4415
5592
|
});
|
|
4416
5593
|
this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
|
|
4417
5594
|
const member = data;
|
|
4418
|
-
this
|
|
5595
|
+
this.#upsertMember(member.guild_id, member);
|
|
4419
5596
|
this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
|
|
4420
5597
|
});
|
|
4421
5598
|
this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
|
|
4422
5599
|
const member = data;
|
|
4423
|
-
this
|
|
5600
|
+
this.#upsertMember(member.guild_id, member);
|
|
4424
5601
|
this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
|
|
4425
5602
|
});
|
|
4426
|
-
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) =>
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
this.#gateway.on("
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
5603
|
+
this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
|
|
5604
|
+
const member = data;
|
|
5605
|
+
this.guilds.members(member.guild_id).delete(member.user.id);
|
|
5606
|
+
this.emit("guildMemberRemove" /* GuildMemberRemove */, member);
|
|
5607
|
+
});
|
|
5608
|
+
this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => {
|
|
5609
|
+
const chunk = data;
|
|
5610
|
+
for (const member of chunk.members)
|
|
5611
|
+
this.#upsertMember(chunk.guild_id, member);
|
|
5612
|
+
this.emit("guildMembersChunk" /* GuildMembersChunk */, chunk);
|
|
5613
|
+
});
|
|
5614
|
+
this.#gateway.on("GUILD_BAN_ADD", (data) => {
|
|
5615
|
+
const ban = data;
|
|
5616
|
+
const bans = this.guilds.bans(ban.guild_id);
|
|
5617
|
+
bans.set(ban.user.id, {
|
|
5618
|
+
reason: bans.get(ban.user.id)?.reason ?? null,
|
|
5619
|
+
user: ban.user
|
|
5620
|
+
});
|
|
5621
|
+
this.guilds.members(ban.guild_id).delete(ban.user.id);
|
|
5622
|
+
this.emit("guildBanAdd" /* GuildBanAdd */, ban);
|
|
5623
|
+
});
|
|
5624
|
+
this.#gateway.on("GUILD_BAN_REMOVE", (data) => {
|
|
5625
|
+
const ban = data;
|
|
5626
|
+
this.guilds.bans(ban.guild_id).delete(ban.user.id);
|
|
5627
|
+
this.emit("guildBanRemove" /* GuildBanRemove */, ban);
|
|
5628
|
+
});
|
|
5629
|
+
this.#gateway.on("GUILD_ROLE_CREATE", (data) => {
|
|
5630
|
+
const event = data;
|
|
5631
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
5632
|
+
this.emit("guildRoleCreate" /* GuildRoleCreate */, event);
|
|
5633
|
+
});
|
|
5634
|
+
this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
|
|
5635
|
+
const event = data;
|
|
5636
|
+
this.#upsertRole(event.guild_id, event.role);
|
|
5637
|
+
this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
|
|
5638
|
+
});
|
|
5639
|
+
this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
|
|
5640
|
+
const event = data;
|
|
5641
|
+
this.guilds.roles(event.guild_id).delete(event.role_id);
|
|
5642
|
+
this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
|
|
5643
|
+
});
|
|
5644
|
+
this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
|
|
5645
|
+
const event = data;
|
|
5646
|
+
if (this.#cache.emojis) {
|
|
5647
|
+
const emojis = this.guilds.emojis(event.guild_id);
|
|
5648
|
+
const current = new Set(event.emojis.map((emoji) => emoji.id));
|
|
5649
|
+
for (const id of [...emojis.cache.keys()])
|
|
5650
|
+
if (!current.has(id))
|
|
5651
|
+
emojis.delete(id);
|
|
5652
|
+
for (const emoji of event.emojis)
|
|
5653
|
+
emojis.upsert(emoji);
|
|
5654
|
+
}
|
|
5655
|
+
this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
|
|
5656
|
+
});
|
|
5657
|
+
this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
|
|
5658
|
+
const event = data;
|
|
5659
|
+
this.guilds.stickers(event.guild_id).sync(event.stickers);
|
|
5660
|
+
this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
|
|
5661
|
+
});
|
|
5662
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
|
|
5663
|
+
const sound = data;
|
|
5664
|
+
if (sound.guild_id)
|
|
5665
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
5666
|
+
this.emit("soundboardSoundCreate" /* SoundboardSoundCreate */, sound);
|
|
5667
|
+
});
|
|
5668
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_UPDATE", (data) => {
|
|
5669
|
+
const sound = data;
|
|
5670
|
+
if (sound.guild_id)
|
|
5671
|
+
this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
|
|
5672
|
+
this.emit("soundboardSoundUpdate" /* SoundboardSoundUpdate */, sound);
|
|
5673
|
+
});
|
|
5674
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUND_DELETE", (data) => {
|
|
5675
|
+
const event = data;
|
|
5676
|
+
this.guilds.soundboard(event.guild_id).delete(event.sound_id);
|
|
5677
|
+
this.emit("soundboardSoundDelete" /* SoundboardSoundDelete */, event);
|
|
5678
|
+
});
|
|
5679
|
+
this.#gateway.on("GUILD_SOUNDBOARD_SOUNDS_UPDATE", (data) => {
|
|
5680
|
+
const event = data;
|
|
5681
|
+
const sounds = this.guilds.soundboard(event.guild_id);
|
|
5682
|
+
sounds.clear();
|
|
5683
|
+
for (const sound of event.soundboard_sounds)
|
|
5684
|
+
sounds.set(sound.sound_id, sound);
|
|
5685
|
+
this.emit("soundboardSoundsUpdate" /* SoundboardSoundsUpdate */, event);
|
|
5686
|
+
});
|
|
5687
|
+
this.#gateway.on("ENTITLEMENT_CREATE", (data) => {
|
|
5688
|
+
const entitlement = data;
|
|
5689
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
5690
|
+
this.emit("entitlementCreate" /* EntitlementCreate */, entitlement);
|
|
5691
|
+
});
|
|
5692
|
+
this.#gateway.on("ENTITLEMENT_UPDATE", (data) => {
|
|
5693
|
+
const entitlement = data;
|
|
5694
|
+
this.monetization?.set(entitlement.id, entitlement);
|
|
5695
|
+
this.emit("entitlementUpdate" /* EntitlementUpdate */, entitlement);
|
|
5696
|
+
});
|
|
5697
|
+
this.#gateway.on("ENTITLEMENT_DELETE", (data) => {
|
|
5698
|
+
const entitlement = data;
|
|
5699
|
+
this.monetization?.delete(entitlement.id);
|
|
5700
|
+
this.emit("entitlementDelete" /* EntitlementDelete */, entitlement);
|
|
5701
|
+
});
|
|
4435
5702
|
this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
|
|
4436
|
-
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) =>
|
|
4437
|
-
|
|
4438
|
-
|
|
5703
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => {
|
|
5704
|
+
const event = data;
|
|
5705
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
5706
|
+
this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, event);
|
|
5707
|
+
});
|
|
5708
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => {
|
|
5709
|
+
const event = data;
|
|
5710
|
+
this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
|
|
5711
|
+
this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, event);
|
|
5712
|
+
});
|
|
5713
|
+
this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => {
|
|
5714
|
+
const event = data;
|
|
5715
|
+
this.guilds.scheduledEvents(event.guild_id).delete(event.id);
|
|
5716
|
+
this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, event);
|
|
5717
|
+
});
|
|
4439
5718
|
this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
|
|
4440
5719
|
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
|
-
|
|
5720
|
+
this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => {
|
|
5721
|
+
const rule = data;
|
|
5722
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
5723
|
+
this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, rule);
|
|
5724
|
+
});
|
|
5725
|
+
this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => {
|
|
5726
|
+
const rule = data;
|
|
5727
|
+
this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
|
|
5728
|
+
this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, rule);
|
|
5729
|
+
});
|
|
5730
|
+
this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => {
|
|
5731
|
+
const rule = data;
|
|
5732
|
+
this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);
|
|
5733
|
+
this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
|
|
5734
|
+
});
|
|
4444
5735
|
this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
|
|
4445
5736
|
this.#gateway.on("CHANNEL_CREATE", (data) => {
|
|
4446
|
-
const channel =
|
|
4447
|
-
this.channels.update(channel);
|
|
5737
|
+
const channel = this.channels.upsert(data);
|
|
4448
5738
|
this.emit("channelCreate" /* ChannelCreate */, channel);
|
|
4449
5739
|
});
|
|
4450
5740
|
this.#gateway.on("CHANNEL_UPDATE", (data) => {
|
|
4451
|
-
const channel =
|
|
4452
|
-
this.channels.update(channel);
|
|
5741
|
+
const channel = this.channels.upsert(data);
|
|
4453
5742
|
this.emit("channelUpdate" /* ChannelUpdate */, channel);
|
|
4454
5743
|
});
|
|
4455
5744
|
this.#gateway.on("CHANNEL_DELETE", (data) => {
|
|
@@ -4459,13 +5748,11 @@ class Client extends EventEmitter2 {
|
|
|
4459
5748
|
});
|
|
4460
5749
|
this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
|
|
4461
5750
|
this.#gateway.on("THREAD_CREATE", (data) => {
|
|
4462
|
-
const channel =
|
|
4463
|
-
this.channels.update(channel);
|
|
5751
|
+
const channel = this.channels.upsert(data);
|
|
4464
5752
|
this.emit("threadCreate" /* ThreadCreate */, channel);
|
|
4465
5753
|
});
|
|
4466
5754
|
this.#gateway.on("THREAD_UPDATE", (data) => {
|
|
4467
|
-
const channel =
|
|
4468
|
-
this.channels.update(channel);
|
|
5755
|
+
const channel = this.channels.upsert(data);
|
|
4469
5756
|
this.emit("threadUpdate" /* ThreadUpdate */, channel);
|
|
4470
5757
|
});
|
|
4471
5758
|
this.#gateway.on("THREAD_DELETE", (data) => {
|
|
@@ -4473,16 +5760,48 @@ class Client extends EventEmitter2 {
|
|
|
4473
5760
|
this.channels.delete(payload.id);
|
|
4474
5761
|
this.emit("threadDelete" /* ThreadDelete */, payload);
|
|
4475
5762
|
});
|
|
4476
|
-
this.#gateway.on("THREAD_LIST_SYNC", (data) =>
|
|
5763
|
+
this.#gateway.on("THREAD_LIST_SYNC", (data) => {
|
|
5764
|
+
const sync = data;
|
|
5765
|
+
for (const thread of sync.threads)
|
|
5766
|
+
this.channels.upsert({ ...thread, guild_id: sync.guild_id });
|
|
5767
|
+
this.emit("threadListSync" /* ThreadListSync */, sync);
|
|
5768
|
+
});
|
|
4477
5769
|
this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
|
|
4478
5770
|
this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
|
|
4479
|
-
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) =>
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
5771
|
+
this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => {
|
|
5772
|
+
const stage = data;
|
|
5773
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
5774
|
+
this.emit("stageInstanceCreate" /* StageInstanceCreate */, stage);
|
|
5775
|
+
});
|
|
5776
|
+
this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => {
|
|
5777
|
+
const stage = data;
|
|
5778
|
+
this.stageInstances.set(stage.channel_id, stage);
|
|
5779
|
+
this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, stage);
|
|
5780
|
+
});
|
|
5781
|
+
this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => {
|
|
5782
|
+
const stage = data;
|
|
5783
|
+
this.stageInstances.delete(stage.channel_id);
|
|
5784
|
+
this.emit("stageInstanceDelete" /* StageInstanceDelete */, stage);
|
|
5785
|
+
});
|
|
5786
|
+
this.#gateway.on("INVITE_CREATE", (data) => {
|
|
5787
|
+
const invite = data;
|
|
5788
|
+
if (invite.guild_id)
|
|
5789
|
+
this.guilds.invites(invite.guild_id).set(invite.code, invite);
|
|
5790
|
+
this.emit("inviteCreate" /* InviteCreate */, invite);
|
|
5791
|
+
});
|
|
5792
|
+
this.#gateway.on("INVITE_DELETE", (data) => {
|
|
5793
|
+
const invite = data;
|
|
5794
|
+
if (invite.guild_id)
|
|
5795
|
+
this.guilds.invites(invite.guild_id).delete(invite.code);
|
|
5796
|
+
this.emit("inviteDelete" /* InviteDelete */, invite);
|
|
5797
|
+
});
|
|
4484
5798
|
this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
|
|
4485
|
-
this.#gateway.on("VOICE_STATE_UPDATE", (data) =>
|
|
5799
|
+
this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
|
|
5800
|
+
const state = data;
|
|
5801
|
+
if (state.guild_id)
|
|
5802
|
+
this.#storeVoiceState(state.guild_id, state);
|
|
5803
|
+
this.emit("voiceStateUpdate" /* VoiceStateUpdate */, state);
|
|
5804
|
+
});
|
|
4486
5805
|
this.#gateway.on("VOICE_SERVER_UPDATE", (data) => this.emit("voiceServerUpdate" /* VoiceServerUpdate */, data));
|
|
4487
5806
|
this.#gateway.on("PRESENCE_UPDATE", (data) => this.emit("presenceUpdate" /* PresenceUpdate */, data));
|
|
4488
5807
|
this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
|
|
@@ -4490,6 +5809,80 @@ class Client extends EventEmitter2 {
|
|
|
4490
5809
|
this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
|
|
4491
5810
|
this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
|
|
4492
5811
|
}
|
|
5812
|
+
#observeMessage(message) {
|
|
5813
|
+
if (!this.channels.has(message.channelId))
|
|
5814
|
+
this.channels.set(message.channelId, message.channel);
|
|
5815
|
+
if (this.#cache.users)
|
|
5816
|
+
this.#merge(this.users, message.author.id, message.author);
|
|
5817
|
+
}
|
|
5818
|
+
#upsertMember(guildId, data) {
|
|
5819
|
+
const member = new GuildMember({ ...data, guild_id: guildId });
|
|
5820
|
+
if (this.#cache.users)
|
|
5821
|
+
this.#merge(this.users, member.user.id, member.user);
|
|
5822
|
+
if (!this.#cache.members)
|
|
5823
|
+
return member;
|
|
5824
|
+
return this.#merge(this.guilds.members(guildId), member.user.id, member);
|
|
5825
|
+
}
|
|
5826
|
+
#storeVoiceState(guildId, state) {
|
|
5827
|
+
const states = this.guilds.voiceStates(guildId);
|
|
5828
|
+
if (state.channel_id)
|
|
5829
|
+
states.set(state.user_id, state);
|
|
5830
|
+
else
|
|
5831
|
+
states.delete(state.user_id);
|
|
5832
|
+
}
|
|
5833
|
+
#upsertRole(guildId, data) {
|
|
5834
|
+
if (!this.#cache.roles)
|
|
5835
|
+
return new Role(data);
|
|
5836
|
+
return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
|
|
5837
|
+
}
|
|
5838
|
+
#merge(manager, id, next) {
|
|
5839
|
+
const existing = manager.get(id);
|
|
5840
|
+
if (!existing) {
|
|
5841
|
+
manager.set(id, next);
|
|
5842
|
+
return next;
|
|
5843
|
+
}
|
|
5844
|
+
for (const [key, value] of Object.entries(next))
|
|
5845
|
+
if (value !== undefined)
|
|
5846
|
+
existing[key] = value;
|
|
5847
|
+
return existing;
|
|
5848
|
+
}
|
|
5849
|
+
createCollector(event, options = {}) {
|
|
5850
|
+
const collector = new Collector(options);
|
|
5851
|
+
let order = 0;
|
|
5852
|
+
const listener = (...args) => {
|
|
5853
|
+
const item = args[0];
|
|
5854
|
+
const id = item?.id;
|
|
5855
|
+
const key = options.key?.(item) ?? (typeof id === "string" ? id : String(order++));
|
|
5856
|
+
collector.handle(key, item).catch((error) => this.emit("error" /* Error */, error instanceof Error ? error : new Error(String(error))));
|
|
5857
|
+
};
|
|
5858
|
+
this.on(event, listener);
|
|
5859
|
+
collector.onDispose(() => this.off(event, listener));
|
|
5860
|
+
return collector;
|
|
5861
|
+
}
|
|
5862
|
+
permissionsFor(memberId, guildOrChannelId) {
|
|
5863
|
+
let channel = this.channels.get(guildOrChannelId);
|
|
5864
|
+
if (channel?.isThread()) {
|
|
5865
|
+
channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
|
|
5866
|
+
if (!channel)
|
|
5867
|
+
return null;
|
|
5868
|
+
}
|
|
5869
|
+
const guildId = channel?.guildId ?? guildOrChannelId;
|
|
5870
|
+
const guild = this.guilds.get(guildId);
|
|
5871
|
+
const member = this.guilds.members(guildId).get(memberId);
|
|
5872
|
+
if (!guild || !member)
|
|
5873
|
+
return null;
|
|
5874
|
+
return computePermissions({
|
|
5875
|
+
guildId,
|
|
5876
|
+
ownerId: guild.ownerId,
|
|
5877
|
+
memberId,
|
|
5878
|
+
memberRoleIds: member.roleIds,
|
|
5879
|
+
roles: this.guilds.roles(guildId).values(),
|
|
5880
|
+
overwrites: channel?.permissionOverwrites
|
|
5881
|
+
});
|
|
5882
|
+
}
|
|
5883
|
+
fetchDefaultSoundboardSounds() {
|
|
5884
|
+
return this.rest.get(Routes.soundboardDefaultSounds());
|
|
5885
|
+
}
|
|
4493
5886
|
async login(token) {
|
|
4494
5887
|
if (this.state === "destroyed")
|
|
4495
5888
|
throw new Error("Cannot login a destroyed client.");
|
|
@@ -4526,6 +5919,14 @@ class Client extends EventEmitter2 {
|
|
|
4526
5919
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
4527
5920
|
return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);
|
|
4528
5921
|
}
|
|
5922
|
+
interactionWebhookMessage(method, applicationId, token, messageId, data) {
|
|
5923
|
+
const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
|
|
5924
|
+
if (method === "GET")
|
|
5925
|
+
return this.rest.get(path);
|
|
5926
|
+
if (method === "PATCH")
|
|
5927
|
+
return this.rest.patch(path, data);
|
|
5928
|
+
return this.rest.delete(path);
|
|
5929
|
+
}
|
|
4529
5930
|
fetchWebhook(id, token) {
|
|
4530
5931
|
return this.rest.get(token ? `/webhooks/${id}/${token}` : `/webhooks/${id}`);
|
|
4531
5932
|
}
|
|
@@ -4583,7 +5984,8 @@ export {
|
|
|
4583
5984
|
PermissionSet,
|
|
4584
5985
|
Permissions,
|
|
4585
5986
|
PermissionsBitField,
|
|
5987
|
+
computePermissions,
|
|
4586
5988
|
resolveGatewayIntents
|
|
4587
5989
|
};
|
|
4588
5990
|
|
|
4589
|
-
//# debugId=
|
|
5991
|
+
//# debugId=29BD1D4A42C8D39264756E2164756E21
|