lunibee 0.2.2 → 0.2.4
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/LICENSE +21 -21
- package/README.md +225 -225
- package/dist/builders/attachment.d.ts +10 -2
- package/dist/builders/commands.d.ts +161 -101
- package/dist/builders/components.d.ts +54 -75
- package/dist/builders/embed.d.ts +68 -35
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +108 -133
- package/dist/builders/index.js.map +8 -8
- package/dist/collection/cache.d.ts +13 -6
- package/dist/collection/index.d.ts +90 -17
- package/dist/collection/index.js +442 -266
- package/dist/collection/index.js.map +4 -4
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +791 -436
- package/dist/core/index.js.map +47 -47
- package/dist/core/permissions.d.ts +9 -5
- package/dist/formatters/index.js +9 -5
- package/dist/formatters/index.js.map +3 -3
- package/dist/handlers/index.js +5 -10
- package/dist/handlers/index.js.map +3 -3
- package/dist/index.js +1010 -679
- package/dist/index.js.map +66 -65
- package/dist/managers/base.d.ts +26 -14
- package/dist/managers/emoji.d.ts +7 -1
- package/dist/managers/guild-resources.d.ts +11 -3
- package/dist/managers/guild.d.ts +13 -5
- package/dist/managers/index.d.ts +28 -14
- package/dist/managers/index.js +580 -340
- package/dist/managers/index.js.map +26 -26
- package/dist/managers/member.d.ts +5 -3
- package/dist/managers/message.d.ts +7 -3
- package/dist/managers/role.d.ts +13 -1
- package/dist/rest/error-codes.d.ts +48 -0
- package/dist/rest/errors.d.ts +14 -6
- package/dist/rest/index.d.ts +25 -12
- package/dist/rest/index.js +105 -18
- package/dist/rest/index.js.map +15 -14
- package/dist/rest/redis.d.ts +1 -1
- package/dist/rest/route.d.ts +8 -4
- package/dist/rest/routes.d.ts +102 -46
- package/dist/rest/transport.d.ts +10 -5
- package/dist/rest/webhook.d.ts +9 -5
- package/dist/sharding/bus.d.ts +34 -17
- package/dist/sharding/index.d.ts +34 -17
- package/dist/sharding/index.js +68 -36
- package/dist/sharding/index.js.map +17 -17
- package/dist/structures/base.d.ts +28 -10
- package/dist/structures/channels.d.ts +28 -14
- package/dist/structures/index.d.ts +6 -6
- package/dist/structures/index.js +81 -99
- package/dist/structures/index.js.map +19 -18
- package/dist/structures/interactions.d.ts +98 -50
- package/dist/structures/resources.d.ts +90 -46
- package/dist/types/gateway.d.ts +1 -1
- package/dist/types/index.d.ts +43 -18
- package/dist/types/index.js +20 -22
- package/dist/types/index.js.map +4 -4
- package/dist/utils/index.js.map +2 -2
- package/dist/voice/index.d.ts +12 -4
- package/dist/voice/index.js +17 -20
- package/dist/voice/index.js.map +3 -3
- package/dist/ws/decoder.d.ts +6 -2
- package/dist/ws/index.d.ts +25 -13
- package/dist/ws/index.js +63 -31
- package/dist/ws/index.js.map +14 -14
- package/dist/ws/protocol.d.ts +10 -2
- package/dist/ws/session.d.ts +14 -4
- package/dist/ws/state.d.ts +22 -11
- package/package.json +16 -15
package/dist/core/index.js
CHANGED
|
@@ -114,60 +114,7 @@ var Permissions = {
|
|
|
114
114
|
PinMessages: 1n << 51n,
|
|
115
115
|
BypassSlowmode: 1n << 52n
|
|
116
116
|
};
|
|
117
|
-
var PermissionFlagsBits =
|
|
118
|
-
CreateInstantInvite: 1n << 0n,
|
|
119
|
-
KickMembers: 1n << 1n,
|
|
120
|
-
BanMembers: 1n << 2n,
|
|
121
|
-
Administrator: 1n << 3n,
|
|
122
|
-
ManageChannels: 1n << 4n,
|
|
123
|
-
ManageGuild: 1n << 5n,
|
|
124
|
-
AddReactions: 1n << 6n,
|
|
125
|
-
ViewAuditLog: 1n << 7n,
|
|
126
|
-
PrioritySpeaker: 1n << 8n,
|
|
127
|
-
Stream: 1n << 9n,
|
|
128
|
-
ViewChannel: 1n << 10n,
|
|
129
|
-
SendMessages: 1n << 11n,
|
|
130
|
-
SendTTSMessages: 1n << 12n,
|
|
131
|
-
ManageMessages: 1n << 13n,
|
|
132
|
-
EmbedLinks: 1n << 14n,
|
|
133
|
-
AttachFiles: 1n << 15n,
|
|
134
|
-
ReadMessageHistory: 1n << 16n,
|
|
135
|
-
MentionEveryone: 1n << 17n,
|
|
136
|
-
UseExternalEmojis: 1n << 18n,
|
|
137
|
-
ViewGuildInsights: 1n << 19n,
|
|
138
|
-
Connect: 1n << 20n,
|
|
139
|
-
Speak: 1n << 21n,
|
|
140
|
-
MuteMembers: 1n << 22n,
|
|
141
|
-
DeafenMembers: 1n << 23n,
|
|
142
|
-
MoveMembers: 1n << 24n,
|
|
143
|
-
UseVAD: 1n << 25n,
|
|
144
|
-
ChangeNickname: 1n << 26n,
|
|
145
|
-
ManageNicknames: 1n << 27n,
|
|
146
|
-
ManageRoles: 1n << 28n,
|
|
147
|
-
ManageWebhooks: 1n << 29n,
|
|
148
|
-
ManageGuildExpressions: 1n << 30n,
|
|
149
|
-
UseApplicationCommands: 1n << 31n,
|
|
150
|
-
RequestToSpeak: 1n << 32n,
|
|
151
|
-
ManageEvents: 1n << 33n,
|
|
152
|
-
ManageThreads: 1n << 34n,
|
|
153
|
-
CreatePublicThreads: 1n << 35n,
|
|
154
|
-
CreatePrivateThreads: 1n << 36n,
|
|
155
|
-
UseExternalStickers: 1n << 37n,
|
|
156
|
-
SendMessagesInThreads: 1n << 38n,
|
|
157
|
-
UseEmbeddedActivities: 1n << 39n,
|
|
158
|
-
ModerateMembers: 1n << 40n,
|
|
159
|
-
ViewCreatorMonetizationAnalytics: 1n << 41n,
|
|
160
|
-
UseSoundboard: 1n << 42n,
|
|
161
|
-
CreateGuildExpressions: 1n << 43n,
|
|
162
|
-
CreateEvents: 1n << 44n,
|
|
163
|
-
UseExternalSounds: 1n << 45n,
|
|
164
|
-
SendVoiceMessages: 1n << 46n,
|
|
165
|
-
SetVoiceChannelStatus: 1n << 48n,
|
|
166
|
-
SendPolls: 1n << 49n,
|
|
167
|
-
UseExternalApps: 1n << 50n,
|
|
168
|
-
PinMessages: 1n << 51n,
|
|
169
|
-
BypassSlowmode: 1n << 52n
|
|
170
|
-
};
|
|
117
|
+
var PermissionFlagsBits = Permissions;
|
|
171
118
|
|
|
172
119
|
class PermissionSet {
|
|
173
120
|
bitfield;
|
|
@@ -468,6 +415,9 @@ function computePermissions(context) {
|
|
|
468
415
|
const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
|
|
469
416
|
if (member)
|
|
470
417
|
base = base & ~bits(member.deny) | bits(member.allow);
|
|
418
|
+
const until = context.timedOutUntil instanceof Date ? context.timedOutUntil.getTime() : context.timedOutUntil ?? 0;
|
|
419
|
+
if (until > Date.now())
|
|
420
|
+
base &= Permission.viewChannel | Permission.readMessageHistory;
|
|
471
421
|
return new PermissionSet(base);
|
|
472
422
|
}
|
|
473
423
|
// packages/core/src/events.ts
|
|
@@ -742,28 +692,26 @@ var IntentBits = {
|
|
|
742
692
|
};
|
|
743
693
|
var Intents = IntentBits;
|
|
744
694
|
function resolveGatewayIntents(intents) {
|
|
745
|
-
if (
|
|
746
|
-
return intents;
|
|
747
|
-
if (
|
|
695
|
+
if (Array.isArray(intents))
|
|
696
|
+
return intents.reduce((acc, intent) => acc | resolveIntent(intent), 0);
|
|
697
|
+
if (typeof intents === "object")
|
|
748
698
|
return intents.bitfield;
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
return 0;
|
|
699
|
+
return resolveIntent(intents);
|
|
700
|
+
}
|
|
701
|
+
function resolveIntent(intent) {
|
|
702
|
+
if (typeof intent === "number")
|
|
703
|
+
return intent;
|
|
704
|
+
const bits = {
|
|
705
|
+
...IntentBits,
|
|
706
|
+
...GatewayIntentBits
|
|
707
|
+
};
|
|
708
|
+
const lower = intent.charAt(0).toLowerCase() + intent.slice(1);
|
|
709
|
+
if (Object.hasOwn(bits, intent))
|
|
710
|
+
return bits[intent];
|
|
711
|
+
if (Object.hasOwn(bits, lower))
|
|
712
|
+
return bits[lower];
|
|
713
|
+
const num = Number(intent);
|
|
714
|
+
return Number.isNaN(num) ? 0 : num;
|
|
767
715
|
}
|
|
768
716
|
|
|
769
717
|
class IntentsBitField {
|
|
@@ -813,67 +761,37 @@ var InteractionResponseEnum = {
|
|
|
813
761
|
Modal: 9
|
|
814
762
|
};
|
|
815
763
|
// packages/collection/src/index.ts
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
this.#unlink(node);
|
|
848
|
-
this.#nodes.delete(key);
|
|
849
|
-
return true;
|
|
850
|
-
}
|
|
851
|
-
clear() {
|
|
852
|
-
this.#nodes.clear();
|
|
853
|
-
this.#oldest = this.#newest = undefined;
|
|
854
|
-
}
|
|
855
|
-
#unlink(node) {
|
|
856
|
-
if (node.older)
|
|
857
|
-
node.older.newer = node.newer;
|
|
858
|
-
else
|
|
859
|
-
this.#oldest = node.newer;
|
|
860
|
-
if (node.newer)
|
|
861
|
-
node.newer.older = node.older;
|
|
862
|
-
else
|
|
863
|
-
this.#newest = node.older;
|
|
864
|
-
node.older = node.newer = undefined;
|
|
865
|
-
}
|
|
866
|
-
#moveNewest(node) {
|
|
867
|
-
if (node === this.#newest)
|
|
868
|
-
return;
|
|
869
|
-
this.#unlink(node);
|
|
870
|
-
node.older = this.#newest;
|
|
871
|
-
if (this.#newest)
|
|
872
|
-
this.#newest.newer = node;
|
|
873
|
-
else
|
|
874
|
-
this.#oldest = node;
|
|
875
|
-
this.#newest = node;
|
|
876
|
-
}
|
|
764
|
+
function newPolicy(options = {}) {
|
|
765
|
+
return {
|
|
766
|
+
ttl: options.ttl,
|
|
767
|
+
maxSize: options.maxSize,
|
|
768
|
+
slide: options.slide ?? true,
|
|
769
|
+
onEvict: options.onEvict,
|
|
770
|
+
expired: 0,
|
|
771
|
+
evicted: 0,
|
|
772
|
+
entries: new Map,
|
|
773
|
+
oldest: undefined,
|
|
774
|
+
newest: undefined,
|
|
775
|
+
lruSize: 0,
|
|
776
|
+
heap: [],
|
|
777
|
+
armedFor: Infinity
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
function peekOf(collection, key) {
|
|
781
|
+
return collection instanceof Map ? Map.prototype.get.call(collection, key) : collection.get(key);
|
|
782
|
+
}
|
|
783
|
+
var mapGet = Map.prototype.get;
|
|
784
|
+
var mapHas = Map.prototype.has;
|
|
785
|
+
function sample(items, amount) {
|
|
786
|
+
if (!Number.isInteger(amount) || amount < 0)
|
|
787
|
+
throw new RangeError("amount must be a non-negative integer.");
|
|
788
|
+
const count = Math.min(amount, items.length);
|
|
789
|
+
for (let i = 0;i < count; i++) {
|
|
790
|
+
const j = i + Math.floor(Math.random() * (items.length - i));
|
|
791
|
+
[items[i], items[j]] = [items[j], items[i]];
|
|
792
|
+
}
|
|
793
|
+
items.length = count;
|
|
794
|
+
return items;
|
|
877
795
|
}
|
|
878
796
|
function assertTTL(ttl) {
|
|
879
797
|
if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
|
|
@@ -881,81 +799,90 @@ function assertTTL(ttl) {
|
|
|
881
799
|
}
|
|
882
800
|
|
|
883
801
|
class Collection extends Map {
|
|
884
|
-
#
|
|
885
|
-
#
|
|
886
|
-
#
|
|
887
|
-
#expiry = new Map;
|
|
888
|
-
#lru = new RecencyList;
|
|
889
|
-
#stats = {
|
|
890
|
-
hits: 0,
|
|
891
|
-
misses: 0,
|
|
892
|
-
expired: 0,
|
|
893
|
-
evicted: 0
|
|
894
|
-
};
|
|
895
|
-
#heap = [];
|
|
896
|
-
#timer;
|
|
897
|
-
#armedFor = Infinity;
|
|
802
|
+
#policy;
|
|
803
|
+
#hits = 0;
|
|
804
|
+
#misses = 0;
|
|
898
805
|
constructor(entries, options = {}) {
|
|
899
806
|
super();
|
|
900
807
|
assertTTL(options.ttl);
|
|
901
808
|
if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
|
|
902
809
|
throw new RangeError("maxSize must be a positive integer.");
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
this.#onEvict = options.onEvict;
|
|
810
|
+
if (options.ttl !== undefined || options.maxSize !== undefined || options.slide !== undefined || options.onEvict !== undefined)
|
|
811
|
+
this.#policy = newPolicy(options);
|
|
906
812
|
if (entries)
|
|
907
813
|
for (const [key, value] of entries)
|
|
908
814
|
this.set(key, value);
|
|
909
815
|
}
|
|
910
816
|
set(key, value, ttl) {
|
|
817
|
+
if (ttl === undefined && this.#policy === undefined)
|
|
818
|
+
return super.set(key, value);
|
|
911
819
|
assertTTL(ttl);
|
|
912
|
-
const window = ttl ?? this.#ttl;
|
|
913
|
-
if (this.#maxSize !== undefined) {
|
|
914
|
-
this.#lru.touch(key);
|
|
915
|
-
}
|
|
916
|
-
super.set(key, value);
|
|
820
|
+
const window = ttl ?? this.#policy?.ttl;
|
|
917
821
|
if (window !== undefined)
|
|
918
|
-
this.#
|
|
919
|
-
|
|
920
|
-
|
|
822
|
+
this.#policy ??= newPolicy();
|
|
823
|
+
if (!this.#policy)
|
|
824
|
+
return super.set(key, value);
|
|
825
|
+
const before = super.size;
|
|
826
|
+
super.set(key, value);
|
|
827
|
+
this.#track(key, value, window, super.size !== before);
|
|
921
828
|
this.#enforceCap();
|
|
922
829
|
return this;
|
|
923
830
|
}
|
|
924
831
|
setWithoutTTL(key, value) {
|
|
925
|
-
if (this.#
|
|
926
|
-
this.#
|
|
927
|
-
if (this.#lru.size > 0)
|
|
928
|
-
this.#lru.delete(key);
|
|
832
|
+
if (this.#policy)
|
|
833
|
+
this.#forget(key);
|
|
929
834
|
super.set(key, value);
|
|
930
835
|
return this;
|
|
931
836
|
}
|
|
932
837
|
get(key) {
|
|
933
|
-
|
|
934
|
-
|
|
838
|
+
const policy = this.#policy;
|
|
839
|
+
const entry = policy?.entries.get(key);
|
|
840
|
+
if (entry === undefined) {
|
|
841
|
+
const value = mapGet.call(this, key);
|
|
842
|
+
if (value !== undefined || mapHas.call(this, key)) {
|
|
843
|
+
this.#hits++;
|
|
844
|
+
return value;
|
|
845
|
+
}
|
|
846
|
+
this.#misses++;
|
|
935
847
|
return;
|
|
936
848
|
}
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
849
|
+
const timed = entry.window !== 0;
|
|
850
|
+
const now = timed ? Date.now() : 0;
|
|
851
|
+
if (timed && entry.deadline <= now) {
|
|
852
|
+
this.#expire(entry);
|
|
853
|
+
this.#misses++;
|
|
940
854
|
return;
|
|
941
855
|
}
|
|
942
|
-
this.#
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
return value;
|
|
856
|
+
this.#hits++;
|
|
857
|
+
if (timed && policy.slide)
|
|
858
|
+
entry.deadline = now + entry.window;
|
|
859
|
+
if (entry.inLru)
|
|
860
|
+
this.#promote(policy, entry);
|
|
861
|
+
return entry.value;
|
|
862
|
+
}
|
|
863
|
+
ensure(key, factory, ttl) {
|
|
864
|
+
const existing = this.get(key);
|
|
865
|
+
if (existing !== undefined || super.has(key))
|
|
866
|
+
return existing;
|
|
867
|
+
const created = factory(key, this);
|
|
868
|
+
this.set(key, created, ttl);
|
|
869
|
+
return created;
|
|
948
870
|
}
|
|
949
871
|
peek(key) {
|
|
950
872
|
if (!this.#expireIfDue(key) && super.has(key)) {
|
|
951
|
-
this.#
|
|
873
|
+
this.#hits++;
|
|
952
874
|
return super.get(key);
|
|
953
875
|
}
|
|
954
|
-
this.#
|
|
876
|
+
this.#misses++;
|
|
955
877
|
return;
|
|
956
878
|
}
|
|
957
879
|
get stats() {
|
|
958
|
-
return {
|
|
880
|
+
return {
|
|
881
|
+
hits: this.#hits,
|
|
882
|
+
misses: this.#misses,
|
|
883
|
+
expired: this.#policy?.expired ?? 0,
|
|
884
|
+
evicted: this.#policy?.evicted ?? 0
|
|
885
|
+
};
|
|
959
886
|
}
|
|
960
887
|
has(key) {
|
|
961
888
|
return !this.#expireIfDue(key) && super.has(key);
|
|
@@ -963,19 +890,23 @@ class Collection extends Map {
|
|
|
963
890
|
delete(key) {
|
|
964
891
|
if (this.#expireIfDue(key))
|
|
965
892
|
return false;
|
|
966
|
-
this.#
|
|
967
|
-
|
|
893
|
+
if (this.#policy)
|
|
894
|
+
this.#forget(key);
|
|
968
895
|
return super.delete(key);
|
|
969
896
|
}
|
|
970
897
|
clear() {
|
|
971
898
|
super.clear();
|
|
972
|
-
this.#
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
899
|
+
const policy = this.#policy;
|
|
900
|
+
if (!policy)
|
|
901
|
+
return;
|
|
902
|
+
policy.entries.clear();
|
|
903
|
+
policy.oldest = policy.newest = undefined;
|
|
904
|
+
policy.lruSize = 0;
|
|
905
|
+
policy.heap.length = 0;
|
|
906
|
+
if (policy.timer)
|
|
907
|
+
clearTimeout(policy.timer);
|
|
908
|
+
policy.timer = undefined;
|
|
909
|
+
policy.armedFor = Infinity;
|
|
979
910
|
}
|
|
980
911
|
get size() {
|
|
981
912
|
this.purge();
|
|
@@ -1003,11 +934,11 @@ class Collection extends Map {
|
|
|
1003
934
|
ttlRemaining(key) {
|
|
1004
935
|
if (this.#expireIfDue(key))
|
|
1005
936
|
return;
|
|
1006
|
-
const
|
|
1007
|
-
return
|
|
937
|
+
const entry = this.#policy?.entries.get(key);
|
|
938
|
+
return entry && entry.window !== 0 ? Math.max(0, entry.deadline - Date.now()) : undefined;
|
|
1008
939
|
}
|
|
1009
940
|
purge() {
|
|
1010
|
-
if (this.#
|
|
941
|
+
if (!this.#policy || this.#policy.heap.length === 0)
|
|
1011
942
|
return 0;
|
|
1012
943
|
const now = Date.now();
|
|
1013
944
|
let removed = 0;
|
|
@@ -1018,133 +949,255 @@ class Collection extends Map {
|
|
|
1018
949
|
this.#remove(due.key);
|
|
1019
950
|
removed++;
|
|
1020
951
|
}
|
|
1021
|
-
this.#
|
|
952
|
+
this.#policy.expired += removed;
|
|
1022
953
|
this.#rearm();
|
|
1023
954
|
for (const [key, value] of dropped)
|
|
1024
955
|
this.#notify(key, value, "expired");
|
|
1025
956
|
return removed;
|
|
1026
957
|
}
|
|
1027
958
|
#expireIfDue(key) {
|
|
1028
|
-
const
|
|
1029
|
-
if (!
|
|
959
|
+
const entry = this.#policy?.entries.get(key);
|
|
960
|
+
if (!entry || entry.window === 0 || entry.deadline > Date.now())
|
|
1030
961
|
return false;
|
|
1031
|
-
|
|
1032
|
-
this.#remove(key);
|
|
1033
|
-
this.#stats.expired++;
|
|
1034
|
-
this.#notify(key, value, "expired");
|
|
962
|
+
this.#expire(entry);
|
|
1035
963
|
return true;
|
|
1036
964
|
}
|
|
965
|
+
#expire(entry) {
|
|
966
|
+
const value = super.get(entry.key);
|
|
967
|
+
this.#remove(entry.key);
|
|
968
|
+
this.#policy.expired++;
|
|
969
|
+
this.#notify(entry.key, value, "expired");
|
|
970
|
+
}
|
|
1037
971
|
#remove(key) {
|
|
1038
|
-
this.#
|
|
1039
|
-
this.#lru.delete(key);
|
|
972
|
+
this.#forget(key);
|
|
1040
973
|
super.delete(key);
|
|
1041
974
|
}
|
|
975
|
+
#forget(key) {
|
|
976
|
+
const policy = this.#policy;
|
|
977
|
+
const entry = policy.entries.get(key);
|
|
978
|
+
if (!entry)
|
|
979
|
+
return;
|
|
980
|
+
if (entry.inLru)
|
|
981
|
+
this.#unlink(policy, entry);
|
|
982
|
+
policy.entries.delete(key);
|
|
983
|
+
}
|
|
984
|
+
#track(key, value, window, isNew) {
|
|
985
|
+
const policy = this.#policy;
|
|
986
|
+
const lru = policy.maxSize !== undefined;
|
|
987
|
+
let entry = isNew ? undefined : policy.entries.get(key);
|
|
988
|
+
if (entry)
|
|
989
|
+
entry.value = value;
|
|
990
|
+
if (window === undefined) {
|
|
991
|
+
if (entry && entry.window !== 0) {
|
|
992
|
+
if (lru)
|
|
993
|
+
entry = this.#replace(policy, entry, 0, 0);
|
|
994
|
+
else {
|
|
995
|
+
this.#forget(key);
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
if (!entry && lru) {
|
|
1000
|
+
entry = this.#create(key, value, 0, 0);
|
|
1001
|
+
policy.entries.set(key, entry);
|
|
1002
|
+
}
|
|
1003
|
+
if (entry)
|
|
1004
|
+
this.#promote(policy, entry);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
const deadline = Date.now() + window;
|
|
1008
|
+
if (entry && entry.window !== 0) {
|
|
1009
|
+
entry.deadline = deadline;
|
|
1010
|
+
entry.window = window;
|
|
1011
|
+
if (deadline < entry.filed)
|
|
1012
|
+
entry = this.#replace(policy, entry, window, deadline);
|
|
1013
|
+
else {
|
|
1014
|
+
if (entry.inLru)
|
|
1015
|
+
this.#promote(policy, entry);
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
} else if (entry) {
|
|
1019
|
+
entry.window = window;
|
|
1020
|
+
entry.deadline = entry.filed = deadline;
|
|
1021
|
+
} else {
|
|
1022
|
+
entry = this.#create(key, value, window, deadline);
|
|
1023
|
+
policy.entries.set(key, entry);
|
|
1024
|
+
}
|
|
1025
|
+
if (lru)
|
|
1026
|
+
this.#promote(policy, entry);
|
|
1027
|
+
this.#heapPush(entry);
|
|
1028
|
+
if (policy.heap.length > 2 * policy.entries.size + 8)
|
|
1029
|
+
this.#compact();
|
|
1030
|
+
if (policy.timer === undefined || deadline < policy.armedFor)
|
|
1031
|
+
this.#rearm();
|
|
1032
|
+
}
|
|
1033
|
+
#create(key, value, window, deadline) {
|
|
1034
|
+
return {
|
|
1035
|
+
key,
|
|
1036
|
+
value,
|
|
1037
|
+
older: undefined,
|
|
1038
|
+
newer: undefined,
|
|
1039
|
+
inLru: false,
|
|
1040
|
+
window,
|
|
1041
|
+
deadline,
|
|
1042
|
+
filed: deadline
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
#replace(policy, old, window, deadline) {
|
|
1046
|
+
const entry = {
|
|
1047
|
+
...old,
|
|
1048
|
+
window,
|
|
1049
|
+
deadline,
|
|
1050
|
+
filed: deadline
|
|
1051
|
+
};
|
|
1052
|
+
if (old.inLru) {
|
|
1053
|
+
if (old.older)
|
|
1054
|
+
old.older.newer = entry;
|
|
1055
|
+
else
|
|
1056
|
+
policy.oldest = entry;
|
|
1057
|
+
if (old.newer)
|
|
1058
|
+
old.newer.older = entry;
|
|
1059
|
+
else
|
|
1060
|
+
policy.newest = entry;
|
|
1061
|
+
}
|
|
1062
|
+
policy.entries.set(old.key, entry);
|
|
1063
|
+
return entry;
|
|
1064
|
+
}
|
|
1065
|
+
#promote(policy, entry) {
|
|
1066
|
+
if (entry === policy.newest)
|
|
1067
|
+
return;
|
|
1068
|
+
if (entry.inLru)
|
|
1069
|
+
this.#unlink(policy, entry, true);
|
|
1070
|
+
else {
|
|
1071
|
+
entry.inLru = true;
|
|
1072
|
+
policy.lruSize++;
|
|
1073
|
+
}
|
|
1074
|
+
entry.older = policy.newest;
|
|
1075
|
+
entry.newer = undefined;
|
|
1076
|
+
if (policy.newest)
|
|
1077
|
+
policy.newest.newer = entry;
|
|
1078
|
+
else
|
|
1079
|
+
policy.oldest = entry;
|
|
1080
|
+
policy.newest = entry;
|
|
1081
|
+
}
|
|
1082
|
+
#unlink(policy, entry, keepCount = false) {
|
|
1083
|
+
if (entry.older)
|
|
1084
|
+
entry.older.newer = entry.newer;
|
|
1085
|
+
else
|
|
1086
|
+
policy.oldest = entry.newer;
|
|
1087
|
+
if (entry.newer)
|
|
1088
|
+
entry.newer.older = entry.older;
|
|
1089
|
+
else
|
|
1090
|
+
policy.newest = entry.older;
|
|
1091
|
+
entry.older = entry.newer = undefined;
|
|
1092
|
+
if (!keepCount) {
|
|
1093
|
+
entry.inLru = false;
|
|
1094
|
+
policy.lruSize--;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
#derived() {
|
|
1098
|
+
const Species = this.constructor[Symbol.species] ?? Collection;
|
|
1099
|
+
return new Species;
|
|
1100
|
+
}
|
|
1042
1101
|
#notify(key, value, reason) {
|
|
1043
|
-
|
|
1102
|
+
const onEvict = this.#policy?.onEvict;
|
|
1103
|
+
if (!onEvict)
|
|
1044
1104
|
return;
|
|
1045
1105
|
try {
|
|
1046
|
-
|
|
1106
|
+
onEvict(key, value, reason);
|
|
1047
1107
|
} catch {}
|
|
1048
1108
|
}
|
|
1049
1109
|
#enforceCap() {
|
|
1050
|
-
|
|
1110
|
+
const policy = this.#policy;
|
|
1111
|
+
const max = policy.maxSize;
|
|
1112
|
+
if (max === undefined)
|
|
1051
1113
|
return;
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
this.#
|
|
1114
|
+
if (policy.lruSize > max && policy.heap.length > 0 && policy.heap[0].filed <= Date.now())
|
|
1115
|
+
this.purge();
|
|
1116
|
+
while (policy.lruSize > max) {
|
|
1117
|
+
const oldest = policy.oldest;
|
|
1118
|
+
const value = policy.onEvict ? super.get(oldest.key) : undefined;
|
|
1119
|
+
this.#unlink(policy, oldest);
|
|
1120
|
+
policy.entries.delete(oldest.key);
|
|
1121
|
+
super.delete(oldest.key);
|
|
1122
|
+
policy.evicted++;
|
|
1123
|
+
this.#notify(oldest.key, value, "evicted");
|
|
1058
1124
|
}
|
|
1059
1125
|
}
|
|
1060
|
-
#schedule(key, window) {
|
|
1061
|
-
const deadline = Date.now() + window;
|
|
1062
|
-
const expiry = this.#expiry.get(key);
|
|
1063
|
-
if (expiry) {
|
|
1064
|
-
expiry.deadline = deadline;
|
|
1065
|
-
expiry.window = window;
|
|
1066
|
-
if (deadline >= expiry.filed)
|
|
1067
|
-
return;
|
|
1068
|
-
expiry.filed = deadline;
|
|
1069
|
-
} else
|
|
1070
|
-
this.#expiry.set(key, { deadline, window, filed: deadline });
|
|
1071
|
-
this.#heapPush({ key, deadline });
|
|
1072
|
-
if (this.#heap.length > 2 * this.#expiry.size + 8)
|
|
1073
|
-
this.#compact();
|
|
1074
|
-
this.#rearm();
|
|
1075
|
-
}
|
|
1076
1126
|
#nextDeadline() {
|
|
1127
|
+
const policy = this.#policy;
|
|
1077
1128
|
for (;; ) {
|
|
1078
|
-
const top =
|
|
1129
|
+
const top = policy.heap[0];
|
|
1079
1130
|
if (top === undefined)
|
|
1080
1131
|
return Infinity;
|
|
1081
|
-
|
|
1082
|
-
if (!expiry || expiry.filed !== top.deadline) {
|
|
1132
|
+
if (policy.entries.get(top.key) !== top) {
|
|
1083
1133
|
this.#heapPop();
|
|
1084
1134
|
continue;
|
|
1085
1135
|
}
|
|
1086
|
-
if (
|
|
1087
|
-
return top.
|
|
1136
|
+
if (top.deadline === top.filed)
|
|
1137
|
+
return top.filed;
|
|
1088
1138
|
this.#heapPop();
|
|
1089
|
-
|
|
1090
|
-
this.#heapPush(
|
|
1139
|
+
top.filed = top.deadline;
|
|
1140
|
+
this.#heapPush(top);
|
|
1091
1141
|
}
|
|
1092
1142
|
}
|
|
1093
1143
|
#compact() {
|
|
1094
|
-
const
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1144
|
+
const policy = this.#policy;
|
|
1145
|
+
const live = policy.heap.filter((entry) => policy.entries.get(entry.key) === entry);
|
|
1146
|
+
policy.heap.length = 0;
|
|
1147
|
+
for (const entry of live)
|
|
1148
|
+
this.#heapPush(entry);
|
|
1098
1149
|
}
|
|
1099
1150
|
#rearm() {
|
|
1151
|
+
const p = this.#policy;
|
|
1100
1152
|
const deadline = this.#nextDeadline();
|
|
1101
|
-
if (
|
|
1153
|
+
if (p.timer !== undefined && deadline >= p.armedFor)
|
|
1102
1154
|
return;
|
|
1103
|
-
if (
|
|
1104
|
-
clearTimeout(
|
|
1105
|
-
|
|
1106
|
-
|
|
1155
|
+
if (p.timer)
|
|
1156
|
+
clearTimeout(p.timer);
|
|
1157
|
+
p.timer = undefined;
|
|
1158
|
+
p.armedFor = deadline;
|
|
1107
1159
|
if (deadline === Infinity)
|
|
1108
1160
|
return;
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1161
|
+
p.timer = setTimeout(() => {
|
|
1162
|
+
p.timer = undefined;
|
|
1163
|
+
p.armedFor = Infinity;
|
|
1112
1164
|
this.purge();
|
|
1113
1165
|
}, Math.max(0, deadline - Date.now()));
|
|
1114
|
-
|
|
1166
|
+
p.timer.unref?.();
|
|
1115
1167
|
}
|
|
1116
|
-
#heapPush(
|
|
1117
|
-
const heap = this.#heap;
|
|
1118
|
-
heap.
|
|
1119
|
-
|
|
1168
|
+
#heapPush(entry) {
|
|
1169
|
+
const heap = this.#policy.heap;
|
|
1170
|
+
let i = heap.length;
|
|
1171
|
+
heap.push(entry);
|
|
1120
1172
|
while (i > 0) {
|
|
1121
1173
|
const parent = i - 1 >> 1;
|
|
1122
|
-
|
|
1174
|
+
const above = heap[parent];
|
|
1175
|
+
if (above.filed <= entry.filed)
|
|
1123
1176
|
break;
|
|
1124
|
-
|
|
1177
|
+
heap[i] = above;
|
|
1125
1178
|
i = parent;
|
|
1126
1179
|
}
|
|
1180
|
+
heap[i] = entry;
|
|
1127
1181
|
}
|
|
1128
1182
|
#heapPop() {
|
|
1129
|
-
const heap = this.#heap;
|
|
1183
|
+
const heap = this.#policy.heap;
|
|
1130
1184
|
const top = heap[0];
|
|
1131
1185
|
const last = heap.pop();
|
|
1132
1186
|
if (top === undefined || heap.length === 0)
|
|
1133
1187
|
return top;
|
|
1134
|
-
|
|
1135
|
-
for (
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
if (
|
|
1140
|
-
|
|
1141
|
-
if (
|
|
1142
|
-
smallest = right;
|
|
1143
|
-
if (smallest === i)
|
|
1188
|
+
let i = 0;
|
|
1189
|
+
for (;; ) {
|
|
1190
|
+
let child = 2 * i + 1;
|
|
1191
|
+
if (child >= heap.length)
|
|
1192
|
+
break;
|
|
1193
|
+
if (child + 1 < heap.length && heap[child + 1].filed < heap[child].filed)
|
|
1194
|
+
child++;
|
|
1195
|
+
if (heap[child].filed >= last.filed)
|
|
1144
1196
|
break;
|
|
1145
|
-
|
|
1146
|
-
i =
|
|
1197
|
+
heap[i] = heap[child];
|
|
1198
|
+
i = child;
|
|
1147
1199
|
}
|
|
1200
|
+
heap[i] = last;
|
|
1148
1201
|
return top;
|
|
1149
1202
|
}
|
|
1150
1203
|
first() {
|
|
@@ -1176,8 +1229,26 @@ class Collection extends Map {
|
|
|
1176
1229
|
}
|
|
1177
1230
|
return;
|
|
1178
1231
|
}
|
|
1232
|
+
findLast(predicate) {
|
|
1233
|
+
const entries = [...this];
|
|
1234
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
1235
|
+
const [key, value] = entries[i];
|
|
1236
|
+
if (predicate(value, key, this))
|
|
1237
|
+
return value;
|
|
1238
|
+
}
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
findLastKey(predicate) {
|
|
1242
|
+
const entries = [...this];
|
|
1243
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
1244
|
+
const [key, value] = entries[i];
|
|
1245
|
+
if (predicate(value, key, this))
|
|
1246
|
+
return key;
|
|
1247
|
+
}
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1179
1250
|
filter(predicate) {
|
|
1180
|
-
const result =
|
|
1251
|
+
const result = this.#derived();
|
|
1181
1252
|
for (const [key, value] of this) {
|
|
1182
1253
|
if (predicate(value, key, this))
|
|
1183
1254
|
result.set(key, value);
|
|
@@ -1221,7 +1292,7 @@ class Collection extends Map {
|
|
|
1221
1292
|
return [...this.entries()];
|
|
1222
1293
|
}
|
|
1223
1294
|
clone() {
|
|
1224
|
-
const copy =
|
|
1295
|
+
const copy = this.#derived();
|
|
1225
1296
|
for (const [key, value] of this)
|
|
1226
1297
|
copy.set(key, value);
|
|
1227
1298
|
return copy;
|
|
@@ -1276,7 +1347,7 @@ class Collection extends Map {
|
|
|
1276
1347
|
return result;
|
|
1277
1348
|
}
|
|
1278
1349
|
intersection(other) {
|
|
1279
|
-
const result =
|
|
1350
|
+
const result = this.#derived();
|
|
1280
1351
|
for (const [key, value] of this) {
|
|
1281
1352
|
if (other.has(key))
|
|
1282
1353
|
result.set(key, value);
|
|
@@ -1284,7 +1355,7 @@ class Collection extends Map {
|
|
|
1284
1355
|
return result;
|
|
1285
1356
|
}
|
|
1286
1357
|
difference(other) {
|
|
1287
|
-
const result =
|
|
1358
|
+
const result = this.#derived();
|
|
1288
1359
|
for (const [key, value] of this) {
|
|
1289
1360
|
if (!other.has(key))
|
|
1290
1361
|
result.set(key, value);
|
|
@@ -1292,8 +1363,8 @@ class Collection extends Map {
|
|
|
1292
1363
|
return result;
|
|
1293
1364
|
}
|
|
1294
1365
|
partition(predicate) {
|
|
1295
|
-
const pass =
|
|
1296
|
-
const fail =
|
|
1366
|
+
const pass = this.#derived();
|
|
1367
|
+
const fail = this.#derived();
|
|
1297
1368
|
for (const [key, value] of this) {
|
|
1298
1369
|
if (predicate(value, key, this))
|
|
1299
1370
|
pass.set(key, value);
|
|
@@ -1302,6 +1373,81 @@ class Collection extends Map {
|
|
|
1302
1373
|
}
|
|
1303
1374
|
return [pass, fail];
|
|
1304
1375
|
}
|
|
1376
|
+
symmetricDifference(other) {
|
|
1377
|
+
const result = this.#derived();
|
|
1378
|
+
for (const [key, value] of this)
|
|
1379
|
+
if (!other.has(key))
|
|
1380
|
+
result.set(key, value);
|
|
1381
|
+
for (const [key, value] of other)
|
|
1382
|
+
if (!this.has(key))
|
|
1383
|
+
result.set(key, value);
|
|
1384
|
+
return result;
|
|
1385
|
+
}
|
|
1386
|
+
concat(...collections) {
|
|
1387
|
+
const result = this.clone();
|
|
1388
|
+
for (const collection of collections)
|
|
1389
|
+
for (const [key, value] of collection)
|
|
1390
|
+
result.set(key, value);
|
|
1391
|
+
return result;
|
|
1392
|
+
}
|
|
1393
|
+
merge(other, whenInSelf, whenInOther, whenInBoth) {
|
|
1394
|
+
const result = this.#derived();
|
|
1395
|
+
const decide = (key, kept) => {
|
|
1396
|
+
if (kept.keep)
|
|
1397
|
+
result.set(key, kept.value);
|
|
1398
|
+
};
|
|
1399
|
+
for (const [key, value] of this) {
|
|
1400
|
+
decide(key, other.has(key) ? whenInBoth(value, peekOf(other, key), key) : whenInSelf(value, key));
|
|
1401
|
+
}
|
|
1402
|
+
for (const [key, value] of other)
|
|
1403
|
+
if (!this.has(key))
|
|
1404
|
+
decide(key, whenInOther(value, key));
|
|
1405
|
+
return result;
|
|
1406
|
+
}
|
|
1407
|
+
equals(other) {
|
|
1408
|
+
if (!other)
|
|
1409
|
+
return false;
|
|
1410
|
+
if (other === this)
|
|
1411
|
+
return true;
|
|
1412
|
+
if (this.size !== other.size)
|
|
1413
|
+
return false;
|
|
1414
|
+
for (const [key, value] of this) {
|
|
1415
|
+
if (!other.has(key))
|
|
1416
|
+
return false;
|
|
1417
|
+
if (value !== peekOf(other, key))
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
return true;
|
|
1421
|
+
}
|
|
1422
|
+
mapValues(transform) {
|
|
1423
|
+
const result = this.#derived();
|
|
1424
|
+
for (const [key, value] of this)
|
|
1425
|
+
result.set(key, transform(value, key, this));
|
|
1426
|
+
return result;
|
|
1427
|
+
}
|
|
1428
|
+
toReversed() {
|
|
1429
|
+
const result = this.#derived();
|
|
1430
|
+
const entries = [...this];
|
|
1431
|
+
for (let i = entries.length - 1;i >= 0; i--)
|
|
1432
|
+
result.set(entries[i][0], entries[i][1]);
|
|
1433
|
+
return result;
|
|
1434
|
+
}
|
|
1435
|
+
toSorted(comparator) {
|
|
1436
|
+
return this.sorted(comparator);
|
|
1437
|
+
}
|
|
1438
|
+
static groupBy(items, keySelector) {
|
|
1439
|
+
const groups = new Collection;
|
|
1440
|
+
let index = 0;
|
|
1441
|
+
for (const item of items)
|
|
1442
|
+
groups.ensure(keySelector(item, index++), () => []).push(item);
|
|
1443
|
+
return groups;
|
|
1444
|
+
}
|
|
1445
|
+
static combineEntries(entries, combine) {
|
|
1446
|
+
const result = new Collection;
|
|
1447
|
+
for (const [key, value] of entries)
|
|
1448
|
+
result.set(key, result.has(key) ? combine(result.get(key), value, key) : value);
|
|
1449
|
+
return result;
|
|
1450
|
+
}
|
|
1305
1451
|
tap(fn) {
|
|
1306
1452
|
fn(this);
|
|
1307
1453
|
return this;
|
|
@@ -1320,6 +1466,13 @@ class Collection extends Map {
|
|
|
1320
1466
|
acc = fn(acc, value, key, this);
|
|
1321
1467
|
return acc;
|
|
1322
1468
|
}
|
|
1469
|
+
reduceRight(fn, initialValue) {
|
|
1470
|
+
const entries = [...this];
|
|
1471
|
+
let acc = initialValue;
|
|
1472
|
+
for (let i = entries.length - 1;i >= 0; i--)
|
|
1473
|
+
acc = fn(acc, entries[i][1], entries[i][0], this);
|
|
1474
|
+
return acc;
|
|
1475
|
+
}
|
|
1323
1476
|
sorted(comparator) {
|
|
1324
1477
|
const decorated = [...this.entries()].map((entry, index) => ({
|
|
1325
1478
|
entry,
|
|
@@ -1330,22 +1483,34 @@ class Collection extends Map {
|
|
|
1330
1483
|
const comparison = comparator(x.entry[1], y.entry[1], x.entry[0], y.entry[0]);
|
|
1331
1484
|
return comparison !== 0 ? comparison : x.index - y.index;
|
|
1332
1485
|
});
|
|
1333
|
-
const result =
|
|
1486
|
+
const result = this.#derived();
|
|
1334
1487
|
for (const { entry } of decorated)
|
|
1335
1488
|
result.set(entry[0], entry[1]);
|
|
1336
1489
|
return result;
|
|
1337
1490
|
}
|
|
1338
|
-
random() {
|
|
1339
|
-
|
|
1340
|
-
|
|
1491
|
+
random(amount) {
|
|
1492
|
+
if (amount !== undefined)
|
|
1493
|
+
return sample([...this.values()], amount);
|
|
1494
|
+
const size = this.size;
|
|
1495
|
+
if (size === 0)
|
|
1341
1496
|
return;
|
|
1342
|
-
|
|
1497
|
+
let index = Math.floor(Math.random() * size);
|
|
1498
|
+
for (const value of this.values())
|
|
1499
|
+
if (index-- === 0)
|
|
1500
|
+
return value;
|
|
1501
|
+
return;
|
|
1343
1502
|
}
|
|
1344
|
-
randomKey() {
|
|
1345
|
-
|
|
1346
|
-
|
|
1503
|
+
randomKey(amount) {
|
|
1504
|
+
if (amount !== undefined)
|
|
1505
|
+
return sample([...this.keys()], amount);
|
|
1506
|
+
const size = this.size;
|
|
1507
|
+
if (size === 0)
|
|
1347
1508
|
return;
|
|
1348
|
-
|
|
1509
|
+
let index = Math.floor(Math.random() * size);
|
|
1510
|
+
for (const key of this.keys())
|
|
1511
|
+
if (index-- === 0)
|
|
1512
|
+
return key;
|
|
1513
|
+
return;
|
|
1349
1514
|
}
|
|
1350
1515
|
at(index) {
|
|
1351
1516
|
const arr = [...this.values()];
|
|
@@ -1363,6 +1528,11 @@ class Collection extends Map {
|
|
|
1363
1528
|
}
|
|
1364
1529
|
|
|
1365
1530
|
// packages/managers/src/base.ts
|
|
1531
|
+
function splitReason(options) {
|
|
1532
|
+
const { reason, ...payload } = options;
|
|
1533
|
+
return [payload, reason];
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1366
1536
|
class Manager {
|
|
1367
1537
|
cache = new Collection;
|
|
1368
1538
|
get(id) {
|
|
@@ -1464,12 +1634,15 @@ class ResourceManager extends Manager {
|
|
|
1464
1634
|
// packages/rest/package.json
|
|
1465
1635
|
var package_default = {
|
|
1466
1636
|
name: "@lunibee/rest",
|
|
1467
|
-
version: "0.2.
|
|
1637
|
+
version: "0.2.4",
|
|
1468
1638
|
type: "module",
|
|
1469
1639
|
module: "./src/index.ts",
|
|
1470
1640
|
types: "./src/index.ts",
|
|
1471
1641
|
exports: {
|
|
1472
1642
|
".": "./src/index.ts"
|
|
1643
|
+
},
|
|
1644
|
+
dependencies: {
|
|
1645
|
+
"@lunibee/types": "workspace:*"
|
|
1473
1646
|
}
|
|
1474
1647
|
};
|
|
1475
1648
|
|
|
@@ -1542,8 +1715,12 @@ function kindFromStatus(status) {
|
|
|
1542
1715
|
return "client";
|
|
1543
1716
|
}
|
|
1544
1717
|
function redactPath(path) {
|
|
1545
|
-
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]
|
|
1718
|
+
return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/i, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/i, "$1:token");
|
|
1546
1719
|
}
|
|
1720
|
+
var HINTS = {
|
|
1721
|
+
50001: "The bot cannot see this resource: check that it is in the guild and has View Channel there.",
|
|
1722
|
+
50013: "The bot lacks a permission for this action, or the target role or member is at or above the bot's highest role."
|
|
1723
|
+
};
|
|
1547
1724
|
|
|
1548
1725
|
class RESTError extends Error {
|
|
1549
1726
|
kind;
|
|
@@ -1552,12 +1729,14 @@ class RESTError extends Error {
|
|
|
1552
1729
|
errors;
|
|
1553
1730
|
method;
|
|
1554
1731
|
path;
|
|
1732
|
+
hint;
|
|
1555
1733
|
constructor(message, status, code, errors, options = {}) {
|
|
1556
1734
|
super(message, options.cause === undefined ? undefined : { cause: options.cause });
|
|
1557
1735
|
this.name = "RESTError";
|
|
1558
1736
|
this.status = status;
|
|
1559
1737
|
this.kind = options.kind ?? kindFromStatus(status);
|
|
1560
1738
|
this.code = code;
|
|
1739
|
+
this.hint = code === undefined ? undefined : HINTS[code];
|
|
1561
1740
|
this.errors = errors;
|
|
1562
1741
|
this.method = options.method;
|
|
1563
1742
|
this.path = options.path === undefined ? undefined : redactPath(options.path);
|
|
@@ -1595,19 +1774,23 @@ async function abortable(promise, signal, path) {
|
|
|
1595
1774
|
}
|
|
1596
1775
|
|
|
1597
1776
|
// packages/rest/src/route.ts
|
|
1777
|
+
import { createHash } from "crypto";
|
|
1598
1778
|
function normalizeRoutePath(path) {
|
|
1599
1779
|
const queryIndex = path.indexOf("?");
|
|
1600
1780
|
const routePath = queryIndex === -1 ? path : path.slice(0, queryIndex);
|
|
1601
|
-
return routePath.replace(/\/\d+(?=\/|$)/g, "/:id");
|
|
1781
|
+
return redactPath(routePath).replace(/\/\d+(?=\/|$)/g, "/:id");
|
|
1602
1782
|
}
|
|
1603
1783
|
function majorParameter(path) {
|
|
1604
|
-
const match = /^\/(channels|guilds|webhooks)\/(\d+)(?:\/([^/?]+))
|
|
1784
|
+
const match = /^\/(channels|guilds|webhooks)\/(\d+)(?:\/([^/?]+))?/i.exec(path);
|
|
1605
1785
|
if (!match)
|
|
1606
1786
|
return "@none";
|
|
1607
|
-
if (match[1] === "webhooks" && match[3] !== undefined)
|
|
1608
|
-
return `${match[2]}:${match[3]}`;
|
|
1787
|
+
if (match[1].toLowerCase() === "webhooks" && match[3] !== undefined)
|
|
1788
|
+
return `${match[2]}:${tokenDigest(match[3])}`;
|
|
1609
1789
|
return match[2];
|
|
1610
1790
|
}
|
|
1791
|
+
function tokenDigest(token) {
|
|
1792
|
+
return createHash("sha256").update(token).digest("hex").slice(0, 16);
|
|
1793
|
+
}
|
|
1611
1794
|
function scopeBucket(hashOrRoute, major) {
|
|
1612
1795
|
return `${hashOrRoute}|${major}`;
|
|
1613
1796
|
}
|
|
@@ -1849,6 +2032,9 @@ var Routes = {
|
|
|
1849
2032
|
user: () => "/users/@me",
|
|
1850
2033
|
userById: (userId) => `/users/${snowflake(userId, "User ID")}`,
|
|
1851
2034
|
guild: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}`,
|
|
2035
|
+
currentUserGuild: (guildId) => `/users/@me/guilds/${snowflake(guildId, "Guild ID")}`,
|
|
2036
|
+
sticker: (stickerId) => `/stickers/${snowflake(stickerId, "Sticker ID")}`,
|
|
2037
|
+
messageReactionUser: (channelId, messageId, emoji, userId) => `${Routes.messageReactions(channelId, messageId, emoji)}/${snowflake(userId, "User ID")}`,
|
|
1852
2038
|
guildPreview: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/preview`,
|
|
1853
2039
|
guildActiveThreads: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/threads/active`,
|
|
1854
2040
|
guildWebhooks: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/webhooks`,
|
|
@@ -1866,6 +2052,8 @@ var Routes = {
|
|
|
1866
2052
|
crosspostMessage: (channelId, messageId) => `${Routes.message(channelId, messageId)}/crosspost`,
|
|
1867
2053
|
messageReactions: (channelId, messageId, emoji) => `${Routes.message(channelId, messageId)}/reactions/${encodeURIComponent(emoji)}`,
|
|
1868
2054
|
messageReactionsAll: (channelId, messageId) => `${Routes.message(channelId, messageId)}/reactions`,
|
|
2055
|
+
channelMessagesPins: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/pins`,
|
|
2056
|
+
channelMessagesPin: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/pins/${snowflake(messageId, "Message ID")}`,
|
|
1869
2057
|
channelPins: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/pins`,
|
|
1870
2058
|
channelPin: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/pins/${snowflake(messageId, "Message ID")}`,
|
|
1871
2059
|
messageThread: (channelId, messageId) => `${Routes.message(channelId, messageId)}/threads`,
|
|
@@ -1928,7 +2116,23 @@ function snowflake(value, field) {
|
|
|
1928
2116
|
// packages/rest/src/index.ts
|
|
1929
2117
|
var LIBRARY_VERSION = package_default.version;
|
|
1930
2118
|
var LIBRARY_URL = "https://github.com/Ekretos/lunibee";
|
|
1931
|
-
var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${
|
|
2119
|
+
var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${LIBRARY_VERSION})`;
|
|
2120
|
+
function assertSafePath(path) {
|
|
2121
|
+
const end = path.search(/[?#]/);
|
|
2122
|
+
const pathname = end === -1 ? path : path.slice(0, end);
|
|
2123
|
+
if (pathname.includes("\\"))
|
|
2124
|
+
throw new TypeError("REST paths must not contain backslashes.");
|
|
2125
|
+
for (const segment of pathname.split("/")) {
|
|
2126
|
+
let decoded;
|
|
2127
|
+
try {
|
|
2128
|
+
decoded = decodeURIComponent(segment);
|
|
2129
|
+
} catch {
|
|
2130
|
+
throw new TypeError("REST path has malformed percent-encoding.");
|
|
2131
|
+
}
|
|
2132
|
+
if (decoded === "." || decoded === "..")
|
|
2133
|
+
throw new TypeError("REST paths must not contain '.' or '..' segments.");
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
1932
2136
|
var REQUEST_DATA_KEYS = new Set([
|
|
1933
2137
|
"body",
|
|
1934
2138
|
"files",
|
|
@@ -2013,6 +2217,7 @@ class REST {
|
|
|
2013
2217
|
throw new TypeError("REST method is required.");
|
|
2014
2218
|
if (!path.startsWith("/"))
|
|
2015
2219
|
throw new TypeError("REST paths must start with '/'.");
|
|
2220
|
+
assertSafePath(path);
|
|
2016
2221
|
const route = createRouteKey(method, path);
|
|
2017
2222
|
const files = options.files;
|
|
2018
2223
|
if (files && files.length > 0 && !(body instanceof FormData))
|
|
@@ -2100,13 +2305,19 @@ class REST {
|
|
|
2100
2305
|
#headers(body, options) {
|
|
2101
2306
|
const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
|
|
2102
2307
|
const headers = { ...options.headers };
|
|
2308
|
+
const set = (name, value) => {
|
|
2309
|
+
for (const key of Object.keys(headers))
|
|
2310
|
+
if (key.toLowerCase() === name.toLowerCase())
|
|
2311
|
+
delete headers[key];
|
|
2312
|
+
headers[name] = value;
|
|
2313
|
+
};
|
|
2103
2314
|
if (options.auth !== false && this.#token)
|
|
2104
|
-
|
|
2105
|
-
|
|
2315
|
+
set("Authorization", `Bot ${this.#token}`);
|
|
2316
|
+
set("User-Agent", USER_AGENT);
|
|
2106
2317
|
if (options.reason !== undefined)
|
|
2107
|
-
|
|
2318
|
+
set("X-Audit-Log-Reason", encodeURIComponent(options.reason));
|
|
2108
2319
|
if (!isFormData)
|
|
2109
|
-
|
|
2320
|
+
set("Content-Type", "application/json");
|
|
2110
2321
|
return headers;
|
|
2111
2322
|
}
|
|
2112
2323
|
#encodeBody(body) {
|
|
@@ -2182,7 +2393,7 @@ function cdnURL(path, hash, options = {}) {
|
|
|
2182
2393
|
const isAnimated = hash.startsWith("a_") && !options.forceStatic;
|
|
2183
2394
|
const ext = options.extension ?? (isAnimated ? "gif" : "png");
|
|
2184
2395
|
const size = options.size ? `?size=${options.size}` : "";
|
|
2185
|
-
return `${CDN_BASE}${path}/${hash}.${ext}${size}`;
|
|
2396
|
+
return `${CDN_BASE}${path}/${encodeURIComponent(hash)}.${ext}${size}`;
|
|
2186
2397
|
}
|
|
2187
2398
|
|
|
2188
2399
|
class User extends BaseStructure {
|
|
@@ -2251,13 +2462,13 @@ class Channel extends BaseStructure {
|
|
|
2251
2462
|
this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
|
|
2252
2463
|
this.#context = context;
|
|
2253
2464
|
}
|
|
2254
|
-
|
|
2465
|
+
send(options) {
|
|
2255
2466
|
if (!this.#context)
|
|
2256
2467
|
throw new Error("This channel is not attached to a client.");
|
|
2257
2468
|
return this.#context.sendMessage(this.id, options);
|
|
2258
2469
|
}
|
|
2259
|
-
|
|
2260
|
-
return this.
|
|
2470
|
+
sendMessage(options) {
|
|
2471
|
+
return this.send(options);
|
|
2261
2472
|
}
|
|
2262
2473
|
edit(options) {
|
|
2263
2474
|
if (!this.#context?.editChannel)
|
|
@@ -2280,10 +2491,10 @@ class Channel extends BaseStructure {
|
|
|
2280
2491
|
editParent(parentId) {
|
|
2281
2492
|
return this.edit({ parent_id: parentId });
|
|
2282
2493
|
}
|
|
2283
|
-
delete() {
|
|
2494
|
+
delete(reason) {
|
|
2284
2495
|
if (!this.#context?.deleteChannel)
|
|
2285
2496
|
throw new Error("This channel is not attached to a client.");
|
|
2286
|
-
return this.#context.deleteChannel(this.id);
|
|
2497
|
+
return this.#context.deleteChannel(this.id, reason);
|
|
2287
2498
|
}
|
|
2288
2499
|
update(options) {
|
|
2289
2500
|
return this.edit(options);
|
|
@@ -2330,6 +2541,15 @@ class Guild extends BaseStructure {
|
|
|
2330
2541
|
mfaLevel;
|
|
2331
2542
|
explicitContentFilter;
|
|
2332
2543
|
defaultMessageNotifications;
|
|
2544
|
+
afkChannelId;
|
|
2545
|
+
afkTimeout;
|
|
2546
|
+
widgetEnabled;
|
|
2547
|
+
widgetChannelId;
|
|
2548
|
+
applicationId;
|
|
2549
|
+
publicUpdatesChannelId;
|
|
2550
|
+
safetyAlertsChannelId;
|
|
2551
|
+
maxPresences;
|
|
2552
|
+
maxVideoChannelUsers;
|
|
2333
2553
|
constructor(data) {
|
|
2334
2554
|
super(data.id);
|
|
2335
2555
|
if (!data.name)
|
|
@@ -2351,14 +2571,22 @@ class Guild extends BaseStructure {
|
|
|
2351
2571
|
this.vanityUrlCode = data.vanity_url_code ?? null;
|
|
2352
2572
|
this.nsfwLevel = data.nsfw_level ?? 0;
|
|
2353
2573
|
this.discoverySplash = data.discovery_splash ?? null;
|
|
2354
|
-
|
|
2355
|
-
this.
|
|
2356
|
-
this.
|
|
2357
|
-
this.
|
|
2358
|
-
this.
|
|
2359
|
-
this.
|
|
2360
|
-
this.
|
|
2361
|
-
this.
|
|
2574
|
+
this.rulesChannelId = data.rules_channel_id ?? null;
|
|
2575
|
+
this.systemChannelId = data.system_channel_id ?? null;
|
|
2576
|
+
this.systemChannelFlags = data.system_channel_flags ?? 0;
|
|
2577
|
+
this.maxMembers = data.max_members ?? 0;
|
|
2578
|
+
this.mfaLevel = data.mfa_level ?? 0;
|
|
2579
|
+
this.explicitContentFilter = data.explicit_content_filter ?? 0;
|
|
2580
|
+
this.defaultMessageNotifications = data.default_message_notifications ?? 0;
|
|
2581
|
+
this.afkChannelId = data.afk_channel_id ?? null;
|
|
2582
|
+
this.afkTimeout = data.afk_timeout;
|
|
2583
|
+
this.widgetEnabled = data.widget_enabled ?? false;
|
|
2584
|
+
this.widgetChannelId = data.widget_channel_id ?? null;
|
|
2585
|
+
this.applicationId = data.application_id ?? null;
|
|
2586
|
+
this.publicUpdatesChannelId = data.public_updates_channel_id ?? null;
|
|
2587
|
+
this.safetyAlertsChannelId = data.safety_alerts_channel_id ?? null;
|
|
2588
|
+
this.maxPresences = data.max_presences ?? null;
|
|
2589
|
+
this.maxVideoChannelUsers = data.max_video_channel_users;
|
|
2362
2590
|
}
|
|
2363
2591
|
iconURL(options = {}) {
|
|
2364
2592
|
if (!this.icon)
|
|
@@ -2455,10 +2683,10 @@ class GuildMember {
|
|
|
2455
2683
|
get permissions() {
|
|
2456
2684
|
if (this.#suppliedPermissions)
|
|
2457
2685
|
return this.#suppliedPermissions;
|
|
2458
|
-
return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds) ?? 0n);
|
|
2686
|
+
return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, undefined, this.timedOutUntil) ?? 0n);
|
|
2459
2687
|
}
|
|
2460
2688
|
permissionsIn(channelId) {
|
|
2461
|
-
const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId);
|
|
2689
|
+
const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId, this.timedOutUntil);
|
|
2462
2690
|
return computed ? new PermissionsBitField(computed) : null;
|
|
2463
2691
|
}
|
|
2464
2692
|
#action(name) {
|
|
@@ -2753,6 +2981,13 @@ var OptionType = {
|
|
|
2753
2981
|
class CommandOptions {
|
|
2754
2982
|
#options;
|
|
2755
2983
|
#resolved;
|
|
2984
|
+
#lookup(kind, id) {
|
|
2985
|
+
const group = this.#resolved?.[kind];
|
|
2986
|
+
if (typeof group !== "object" || group === null)
|
|
2987
|
+
return;
|
|
2988
|
+
const entry = group[id];
|
|
2989
|
+
return typeof entry === "object" && entry !== null ? entry : undefined;
|
|
2990
|
+
}
|
|
2756
2991
|
constructor(options, resolved = {}) {
|
|
2757
2992
|
let currentOptions = options;
|
|
2758
2993
|
let group = null;
|
|
@@ -2841,7 +3076,7 @@ class CommandOptions {
|
|
|
2841
3076
|
return null;
|
|
2842
3077
|
}
|
|
2843
3078
|
const userId = String(opt.value);
|
|
2844
|
-
const resolved = this.#
|
|
3079
|
+
const resolved = this.#lookup("users", userId) ?? null;
|
|
2845
3080
|
if (!resolved && required)
|
|
2846
3081
|
throw new TypeError(`Resolved user for option "${name}" is missing.`);
|
|
2847
3082
|
return resolved;
|
|
@@ -2854,7 +3089,7 @@ class CommandOptions {
|
|
|
2854
3089
|
return null;
|
|
2855
3090
|
}
|
|
2856
3091
|
const channelId = String(opt.value);
|
|
2857
|
-
const resolved = this.#
|
|
3092
|
+
const resolved = this.#lookup("channels", channelId) ?? null;
|
|
2858
3093
|
if (!resolved && required)
|
|
2859
3094
|
throw new TypeError(`Resolved channel for option "${name}" is missing.`);
|
|
2860
3095
|
return resolved;
|
|
@@ -2867,7 +3102,7 @@ class CommandOptions {
|
|
|
2867
3102
|
return null;
|
|
2868
3103
|
}
|
|
2869
3104
|
const roleId = String(opt.value);
|
|
2870
|
-
const resolved = this.#
|
|
3105
|
+
const resolved = this.#lookup("roles", roleId) ?? null;
|
|
2871
3106
|
if (!resolved && required)
|
|
2872
3107
|
throw new TypeError(`Resolved role for option "${name}" is missing.`);
|
|
2873
3108
|
return resolved;
|
|
@@ -2880,7 +3115,7 @@ class CommandOptions {
|
|
|
2880
3115
|
return null;
|
|
2881
3116
|
}
|
|
2882
3117
|
const id = String(opt.value);
|
|
2883
|
-
const resolved = this.#
|
|
3118
|
+
const resolved = this.#lookup("users", id) ?? this.#lookup("roles", id) ?? null;
|
|
2884
3119
|
if (!resolved && required)
|
|
2885
3120
|
throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
|
|
2886
3121
|
return resolved;
|
|
@@ -2890,9 +3125,9 @@ class CommandOptions {
|
|
|
2890
3125
|
if (!opt || opt.type !== OptionType.Mentionable)
|
|
2891
3126
|
return null;
|
|
2892
3127
|
const id = String(opt.value);
|
|
2893
|
-
if (this.#
|
|
3128
|
+
if (this.#lookup("users", id))
|
|
2894
3129
|
return "user";
|
|
2895
|
-
if (this.#
|
|
3130
|
+
if (this.#lookup("roles", id))
|
|
2896
3131
|
return "role";
|
|
2897
3132
|
return null;
|
|
2898
3133
|
}
|
|
@@ -2904,7 +3139,7 @@ class CommandOptions {
|
|
|
2904
3139
|
return null;
|
|
2905
3140
|
}
|
|
2906
3141
|
const attachmentId = String(opt.value);
|
|
2907
|
-
const resolved = this.#
|
|
3142
|
+
const resolved = this.#lookup("attachments", attachmentId) ?? null;
|
|
2908
3143
|
if (!resolved && required)
|
|
2909
3144
|
throw new TypeError(`Resolved attachment for option "${name}" is missing.`);
|
|
2910
3145
|
return resolved;
|
|
@@ -3208,16 +3443,19 @@ class ContextMenuCommandInteraction extends CommandInteraction {
|
|
|
3208
3443
|
|
|
3209
3444
|
class ComponentInteraction extends Interaction {
|
|
3210
3445
|
get customId() {
|
|
3211
|
-
|
|
3446
|
+
const id = this.data.data?.custom_id;
|
|
3447
|
+
return typeof id === "string" ? id : "";
|
|
3212
3448
|
}
|
|
3213
3449
|
get messageId() {
|
|
3214
|
-
return this.data
|
|
3450
|
+
return this.data.message?.id;
|
|
3215
3451
|
}
|
|
3216
3452
|
get componentType() {
|
|
3217
|
-
|
|
3453
|
+
const type = this.data.data?.component_type;
|
|
3454
|
+
return typeof type === "number" ? type : 0;
|
|
3218
3455
|
}
|
|
3219
3456
|
get values() {
|
|
3220
|
-
|
|
3457
|
+
const values = this.data.data?.values;
|
|
3458
|
+
return Array.isArray(values) ? values : [];
|
|
3221
3459
|
}
|
|
3222
3460
|
async deferUpdate(options = {}) {
|
|
3223
3461
|
const withResponse = options.withResponse === true;
|
|
@@ -3229,10 +3467,11 @@ class ComponentInteraction extends Interaction {
|
|
|
3229
3467
|
|
|
3230
3468
|
class ModalSubmitInteraction extends Interaction {
|
|
3231
3469
|
get customId() {
|
|
3232
|
-
|
|
3470
|
+
const id = this.data.data?.custom_id;
|
|
3471
|
+
return typeof id === "string" ? id : "";
|
|
3233
3472
|
}
|
|
3234
3473
|
getInputValue(customId) {
|
|
3235
|
-
const rows = this.data
|
|
3474
|
+
const rows = this.data.data?.components ?? [];
|
|
3236
3475
|
for (const row of rows) {
|
|
3237
3476
|
for (const comp of row.components ?? []) {
|
|
3238
3477
|
if (comp.custom_id === customId)
|
|
@@ -3256,11 +3495,12 @@ class AutocompleteInteraction extends Interaction {
|
|
|
3256
3495
|
this.options = new CommandOptions(data.data?.options ?? []);
|
|
3257
3496
|
}
|
|
3258
3497
|
get commandName() {
|
|
3259
|
-
|
|
3498
|
+
const name = this.data.data?.name;
|
|
3499
|
+
return typeof name === "string" ? name : "";
|
|
3260
3500
|
}
|
|
3261
3501
|
get focusedOption() {
|
|
3262
|
-
const options = this.data
|
|
3263
|
-
return findFocused(options);
|
|
3502
|
+
const options = this.data.data?.options;
|
|
3503
|
+
return findFocused(Array.isArray(options) ? options : []);
|
|
3264
3504
|
}
|
|
3265
3505
|
async respond(choices) {
|
|
3266
3506
|
if (!Array.isArray(choices))
|
|
@@ -3377,10 +3617,10 @@ class Message extends BaseStructure {
|
|
|
3377
3617
|
update(options) {
|
|
3378
3618
|
return this.edit(options);
|
|
3379
3619
|
}
|
|
3380
|
-
delete() {
|
|
3620
|
+
delete(reason) {
|
|
3381
3621
|
if (!this.#context)
|
|
3382
3622
|
throw new Error("This message is not attached to a client.");
|
|
3383
|
-
return this.#context.deleteMessage(this.channelId, this.id);
|
|
3623
|
+
return this.#context.deleteMessage(this.channelId, this.id, reason);
|
|
3384
3624
|
}
|
|
3385
3625
|
reply(options) {
|
|
3386
3626
|
if (!this.#context)
|
|
@@ -3427,15 +3667,15 @@ class Message extends BaseStructure {
|
|
|
3427
3667
|
throw new Error("This message is not attached to a client.");
|
|
3428
3668
|
return this.#context.removeAllReactions(this.channelId, this.id);
|
|
3429
3669
|
}
|
|
3430
|
-
pin() {
|
|
3670
|
+
pin(reason) {
|
|
3431
3671
|
if (!this.#context?.pinMessage)
|
|
3432
3672
|
throw new Error("This message is not attached to a client.");
|
|
3433
|
-
return this.#context.pinMessage(this.channelId, this.id);
|
|
3673
|
+
return this.#context.pinMessage(this.channelId, this.id, reason);
|
|
3434
3674
|
}
|
|
3435
|
-
unpin() {
|
|
3675
|
+
unpin(reason) {
|
|
3436
3676
|
if (!this.#context?.unpinMessage)
|
|
3437
3677
|
throw new Error("This message is not attached to a client.");
|
|
3438
|
-
return this.#context.unpinMessage(this.channelId, this.id);
|
|
3678
|
+
return this.#context.unpinMessage(this.channelId, this.id, reason);
|
|
3439
3679
|
}
|
|
3440
3680
|
get isEphemeral() {
|
|
3441
3681
|
return (this.flags & 64) !== 0;
|
|
@@ -3589,7 +3829,7 @@ class UserManager extends ResourceManager {
|
|
|
3589
3829
|
return this.upsert(new User(data));
|
|
3590
3830
|
}
|
|
3591
3831
|
async leaveGuild(guildId) {
|
|
3592
|
-
await this.#rest.delete(
|
|
3832
|
+
await this.#rest.delete(Routes.currentUserGuild(guildId));
|
|
3593
3833
|
}
|
|
3594
3834
|
async createDM(userId) {
|
|
3595
3835
|
return this.#rest.post("/users/@me/channels", {
|
|
@@ -3614,15 +3854,22 @@ class EmojiManager extends Manager {
|
|
|
3614
3854
|
return data.map((item) => this.upsert(item));
|
|
3615
3855
|
}
|
|
3616
3856
|
async create(options) {
|
|
3617
|
-
|
|
3857
|
+
const [payload, reason] = splitReason(options);
|
|
3858
|
+
return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), payload, { reason }));
|
|
3618
3859
|
}
|
|
3619
3860
|
async edit(emojiId, options) {
|
|
3620
|
-
|
|
3861
|
+
const [payload, reason] = splitReason(options);
|
|
3862
|
+
return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), payload, { reason }));
|
|
3621
3863
|
}
|
|
3622
|
-
async
|
|
3623
|
-
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId)
|
|
3864
|
+
async remove(emojiId, reason) {
|
|
3865
|
+
await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId), {
|
|
3866
|
+
reason
|
|
3867
|
+
});
|
|
3624
3868
|
this.delete(emojiId);
|
|
3625
3869
|
}
|
|
3870
|
+
deleteEmoji(emojiId) {
|
|
3871
|
+
return this.remove(emojiId);
|
|
3872
|
+
}
|
|
3626
3873
|
upsert(data) {
|
|
3627
3874
|
const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
|
|
3628
3875
|
return this.#merge(key, new Emoji(data));
|
|
@@ -3826,11 +4073,16 @@ class GuildMemberManager extends ResourceManager {
|
|
|
3826
4073
|
await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
|
|
3827
4074
|
this.delete(userId);
|
|
3828
4075
|
}
|
|
3829
|
-
async unban(userId) {
|
|
3830
|
-
await this.#rest.delete(Routes.guildBan(this.guildId, userId)
|
|
4076
|
+
async unban(userId, reason) {
|
|
4077
|
+
await this.#rest.delete(Routes.guildBan(this.guildId, userId), {
|
|
4078
|
+
reason
|
|
4079
|
+
});
|
|
3831
4080
|
}
|
|
3832
4081
|
async edit(userId, options, reason) {
|
|
3833
|
-
const
|
|
4082
|
+
const [payload, optionsReason] = splitReason(options);
|
|
4083
|
+
const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), payload, {
|
|
4084
|
+
reason: optionsReason ?? reason
|
|
4085
|
+
});
|
|
3834
4086
|
const member = new GuildMember({ ...data, guild_id: this.guildId }, this.#context());
|
|
3835
4087
|
this.set(member.user.id, member);
|
|
3836
4088
|
return member;
|
|
@@ -3866,28 +4118,43 @@ class RoleManager extends ResourceManager {
|
|
|
3866
4118
|
}
|
|
3867
4119
|
async create(options) {
|
|
3868
4120
|
const { reason, ...payload } = options;
|
|
3869
|
-
const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
|
|
3870
|
-
|
|
3871
|
-
permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
|
|
3872
|
-
});
|
|
3873
|
-
const role = new Role(data);
|
|
3874
|
-
this.set(role.id, role);
|
|
3875
|
-
return role;
|
|
4121
|
+
const data = await this.#rest.post(Routes.guildRoles(this.guildId), rolePayload(payload), { reason });
|
|
4122
|
+
return this.#store(data);
|
|
3876
4123
|
}
|
|
3877
4124
|
async edit(roleId, options) {
|
|
3878
4125
|
const { reason, ...payload } = options;
|
|
3879
|
-
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
4126
|
+
const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), rolePayload(payload), { reason });
|
|
4127
|
+
return this.#store(data);
|
|
4128
|
+
}
|
|
4129
|
+
#store(data) {
|
|
3883
4130
|
const role = new Role(data);
|
|
3884
4131
|
this.set(role.id, role);
|
|
3885
4132
|
return role;
|
|
3886
4133
|
}
|
|
3887
|
-
async
|
|
3888
|
-
await this.#rest.delete(Routes.guildRole(this.guildId, roleId)
|
|
4134
|
+
async remove(roleId, reason) {
|
|
4135
|
+
await this.#rest.delete(Routes.guildRole(this.guildId, roleId), {
|
|
4136
|
+
reason
|
|
4137
|
+
});
|
|
3889
4138
|
this.delete(roleId);
|
|
3890
4139
|
}
|
|
4140
|
+
async setPositions(positions, reason) {
|
|
4141
|
+
const data = await this.#rest.patch(Routes.guildRoles(this.guildId), positions.map(({ id, position }) => ({ id, position })), { reason });
|
|
4142
|
+
return data.map((item) => {
|
|
4143
|
+
const role = new Role(item);
|
|
4144
|
+
this.set(role.id, role);
|
|
4145
|
+
return role;
|
|
4146
|
+
});
|
|
4147
|
+
}
|
|
4148
|
+
deleteRole(roleId) {
|
|
4149
|
+
return this.remove(roleId);
|
|
4150
|
+
}
|
|
4151
|
+
}
|
|
4152
|
+
function rolePayload(options) {
|
|
4153
|
+
const { permissions, ...rest } = options;
|
|
4154
|
+
return {
|
|
4155
|
+
...rest,
|
|
4156
|
+
permissions: permissions !== undefined ? String(permissions) : undefined
|
|
4157
|
+
};
|
|
3891
4158
|
}
|
|
3892
4159
|
|
|
3893
4160
|
// packages/managers/src/guild-resources.ts
|
|
@@ -3959,13 +4226,15 @@ class GuildScheduledEventManager extends Manager {
|
|
|
3959
4226
|
return events.map((event) => this.#store(event));
|
|
3960
4227
|
}
|
|
3961
4228
|
async create(options, reason) {
|
|
3962
|
-
|
|
4229
|
+
const [payload, optionsReason] = splitReason(options);
|
|
4230
|
+
return this.#store(await this.#rest.post(Routes.guildScheduledEvents(this.guildId), payload, { reason: optionsReason ?? reason }));
|
|
3963
4231
|
}
|
|
3964
4232
|
async edit(eventId, options, reason) {
|
|
3965
|
-
|
|
4233
|
+
const [payload, optionsReason] = splitReason(options);
|
|
4234
|
+
return this.#store(await this.#rest.patch(Routes.guildScheduledEvent(this.guildId, eventId), payload, { reason: optionsReason ?? reason }));
|
|
3966
4235
|
}
|
|
3967
|
-
async remove(eventId) {
|
|
3968
|
-
await this.#rest.delete(Routes.guildScheduledEvent(this.guildId, eventId));
|
|
4236
|
+
async remove(eventId, reason) {
|
|
4237
|
+
await this.#rest.delete(Routes.guildScheduledEvent(this.guildId, eventId), { reason });
|
|
3969
4238
|
this.delete(eventId);
|
|
3970
4239
|
}
|
|
3971
4240
|
async fetchSubscribers(eventId, options = {}) {
|
|
@@ -3996,13 +4265,13 @@ class StageInstanceManager extends Manager {
|
|
|
3996
4265
|
privacy_level: options.privacyLevel,
|
|
3997
4266
|
send_start_notification: options.sendStartNotification,
|
|
3998
4267
|
guild_scheduled_event_id: options.guildScheduledEventId
|
|
3999
|
-
}, { reason }));
|
|
4268
|
+
}, { reason: options.reason ?? reason }));
|
|
4000
4269
|
}
|
|
4001
4270
|
async fetch(channelId) {
|
|
4002
4271
|
return this.#store(await this.#rest.get(Routes.stageInstanceByChannel(channelId)));
|
|
4003
4272
|
}
|
|
4004
4273
|
async edit(channelId, options, reason) {
|
|
4005
|
-
return this.#store(await this.#rest.patch(Routes.stageInstanceByChannel(channelId), { topic: options.topic, privacy_level: options.privacyLevel }, { reason }));
|
|
4274
|
+
return this.#store(await this.#rest.patch(Routes.stageInstanceByChannel(channelId), { topic: options.topic, privacy_level: options.privacyLevel }, { reason: options.reason ?? reason }));
|
|
4006
4275
|
}
|
|
4007
4276
|
async remove(channelId, reason) {
|
|
4008
4277
|
await this.#rest.delete(Routes.stageInstanceByChannel(channelId), {
|
|
@@ -4039,7 +4308,7 @@ class PermissionOverwriteManager {
|
|
|
4039
4308
|
type: options.type,
|
|
4040
4309
|
allow: BigInt(options.allow ?? 0).toString(),
|
|
4041
4310
|
deny: BigInt(options.deny ?? 0).toString()
|
|
4042
|
-
}, { reason });
|
|
4311
|
+
}, { reason: options.reason ?? reason });
|
|
4043
4312
|
}
|
|
4044
4313
|
async remove(overwriteId, reason) {
|
|
4045
4314
|
await this.#rest.delete(Routes.channelPermission(this.channelId, overwriteId), { reason });
|
|
@@ -4157,12 +4426,16 @@ class GuildManager extends ResourceManager {
|
|
|
4157
4426
|
return this.upsert(new Guild(data));
|
|
4158
4427
|
}
|
|
4159
4428
|
async edit(id, options) {
|
|
4160
|
-
const
|
|
4429
|
+
const [payload, reason] = splitReason(options);
|
|
4430
|
+
const data = await this.#rest.patch(Routes.guild(id), payload, { reason });
|
|
4161
4431
|
return this.upsert(new Guild(data));
|
|
4162
4432
|
}
|
|
4163
|
-
async
|
|
4433
|
+
async remove(id) {
|
|
4164
4434
|
await this.#rest.delete(Routes.guild(id));
|
|
4165
4435
|
}
|
|
4436
|
+
deleteGuild(id) {
|
|
4437
|
+
return this.remove(id);
|
|
4438
|
+
}
|
|
4166
4439
|
async fetchPreview(id) {
|
|
4167
4440
|
return this.#rest.get(Routes.guildPreview(id));
|
|
4168
4441
|
}
|
|
@@ -4206,15 +4479,17 @@ class GuildManager extends ResourceManager {
|
|
|
4206
4479
|
return new AutoModerationRule(rule);
|
|
4207
4480
|
}
|
|
4208
4481
|
async createAutoModerationRule(guildId, options) {
|
|
4209
|
-
const
|
|
4482
|
+
const [payload, reason] = splitReason(options);
|
|
4483
|
+
const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), payload, { reason });
|
|
4210
4484
|
return new AutoModerationRule(rule);
|
|
4211
4485
|
}
|
|
4212
4486
|
async editAutoModerationRule(guildId, ruleId, options) {
|
|
4213
|
-
const
|
|
4487
|
+
const [payload, reason] = splitReason(options);
|
|
4488
|
+
const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), payload, { reason });
|
|
4214
4489
|
return new AutoModerationRule(rule);
|
|
4215
4490
|
}
|
|
4216
|
-
async deleteAutoModerationRule(guildId, ruleId) {
|
|
4217
|
-
await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId));
|
|
4491
|
+
async deleteAutoModerationRule(guildId, ruleId, reason) {
|
|
4492
|
+
await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId), { reason });
|
|
4218
4493
|
}
|
|
4219
4494
|
}
|
|
4220
4495
|
// packages/managers/src/application.ts
|
|
@@ -4277,16 +4552,16 @@ class ChannelManager extends Manager {
|
|
|
4277
4552
|
this.#context = {
|
|
4278
4553
|
sendMessage: (channelId, options) => this.send(channelId, options),
|
|
4279
4554
|
editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
|
|
4280
|
-
deleteMessage: (channelId, messageId) => this.deleteMessage(channelId, messageId),
|
|
4555
|
+
deleteMessage: (channelId, messageId, reason) => this.deleteMessage(channelId, messageId, reason),
|
|
4281
4556
|
crosspostMessage: (channelId, messageId) => this.crosspostMessage(channelId, messageId),
|
|
4282
4557
|
editChannel: (channelId, options) => this.edit(channelId, options),
|
|
4283
|
-
deleteChannel: (channelId) => this.
|
|
4558
|
+
deleteChannel: (channelId, reason) => this.remove(channelId, reason),
|
|
4284
4559
|
addReaction: (channelId, messageId, emoji) => this.addReaction(channelId, messageId, emoji),
|
|
4285
4560
|
removeOwnReaction: (channelId, messageId, emoji) => this.removeOwnReaction(channelId, messageId, emoji),
|
|
4286
4561
|
removeReaction: (channelId, messageId, emoji, userId) => this.removeReaction(channelId, messageId, emoji, userId),
|
|
4287
4562
|
removeAllReactions: (channelId, messageId) => this.removeAllReactions(channelId, messageId),
|
|
4288
|
-
pinMessage: (channelId, messageId) => this.pinMessage(channelId, messageId),
|
|
4289
|
-
unpinMessage: (channelId, messageId) => this.unpinMessage(channelId, messageId)
|
|
4563
|
+
pinMessage: (channelId, messageId, reason) => this.pinMessage(channelId, messageId, reason),
|
|
4564
|
+
unpinMessage: (channelId, messageId, reason) => this.unpinMessage(channelId, messageId, reason)
|
|
4290
4565
|
};
|
|
4291
4566
|
}
|
|
4292
4567
|
messages(channelId) {
|
|
@@ -4356,15 +4631,20 @@ class ChannelManager extends Manager {
|
|
|
4356
4631
|
return this.#messageManagers.get(channelId);
|
|
4357
4632
|
}
|
|
4358
4633
|
async create(guildId, options) {
|
|
4359
|
-
|
|
4634
|
+
const [payload, reason] = splitReason(options);
|
|
4635
|
+
return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), payload, { reason }));
|
|
4360
4636
|
}
|
|
4361
4637
|
async edit(channelId, options) {
|
|
4362
|
-
|
|
4638
|
+
const [payload, reason] = splitReason(options);
|
|
4639
|
+
return this.upsert(await this.#rest.patch(Routes.channel(channelId), payload, { reason }));
|
|
4363
4640
|
}
|
|
4364
|
-
async
|
|
4365
|
-
await this.#rest.delete(Routes.channel(channelId));
|
|
4641
|
+
async remove(channelId, reason) {
|
|
4642
|
+
await this.#rest.delete(Routes.channel(channelId), { reason });
|
|
4366
4643
|
this.delete(channelId);
|
|
4367
4644
|
}
|
|
4645
|
+
deleteChannel(channelId) {
|
|
4646
|
+
return this.remove(channelId);
|
|
4647
|
+
}
|
|
4368
4648
|
delete(channelId) {
|
|
4369
4649
|
this.#messageManagers.delete(channelId);
|
|
4370
4650
|
return super.delete(channelId);
|
|
@@ -4400,8 +4680,10 @@ class ChannelManager extends Manager {
|
|
|
4400
4680
|
async editMessage(channelId, messageId, options) {
|
|
4401
4681
|
return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options, this.#allowedMentions)));
|
|
4402
4682
|
}
|
|
4403
|
-
async deleteMessage(channelId, messageId) {
|
|
4404
|
-
await this.#rest.delete(Routes.message(channelId, messageId)
|
|
4683
|
+
async deleteMessage(channelId, messageId, reason) {
|
|
4684
|
+
await this.#rest.delete(Routes.message(channelId, messageId), {
|
|
4685
|
+
reason
|
|
4686
|
+
});
|
|
4405
4687
|
this.messages(channelId).delete(messageId);
|
|
4406
4688
|
}
|
|
4407
4689
|
deleteCachedMessage(channelId, messageId) {
|
|
@@ -4410,19 +4692,17 @@ class ChannelManager extends Manager {
|
|
|
4410
4692
|
async crosspostMessage(channelId, messageId) {
|
|
4411
4693
|
return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
|
|
4412
4694
|
}
|
|
4413
|
-
async bulkDeleteMessages(channelId, messageIds) {
|
|
4695
|
+
async bulkDeleteMessages(channelId, messageIds, reason) {
|
|
4414
4696
|
const ids = [...new Set(messageIds)];
|
|
4415
4697
|
if (ids.length < 1 || ids.length > 100)
|
|
4416
4698
|
throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
|
|
4417
4699
|
if (ids.length === 1)
|
|
4418
|
-
return this.deleteMessage(channelId, ids[0]);
|
|
4700
|
+
return this.deleteMessage(channelId, ids[0], reason);
|
|
4419
4701
|
const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
|
|
4420
4702
|
const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
|
|
4421
4703
|
if (tooOld.length)
|
|
4422
4704
|
throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
|
|
4423
|
-
await this.#rest.post(Routes.channelBulkDelete(channelId), {
|
|
4424
|
-
messages: ids
|
|
4425
|
-
});
|
|
4705
|
+
await this.#rest.post(Routes.channelBulkDelete(channelId), { messages: ids }, { reason });
|
|
4426
4706
|
for (const id of ids)
|
|
4427
4707
|
this.messages(channelId).delete(id);
|
|
4428
4708
|
}
|
|
@@ -4459,20 +4739,26 @@ class ChannelManager extends Manager {
|
|
|
4459
4739
|
await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
|
|
4460
4740
|
}
|
|
4461
4741
|
async removeReaction(channelId, messageId, emoji, userId) {
|
|
4462
|
-
await this.#rest.delete(
|
|
4742
|
+
await this.#rest.delete(Routes.messageReactionUser(channelId, messageId, emoji, userId));
|
|
4463
4743
|
}
|
|
4464
4744
|
async removeAllReactions(channelId, messageId) {
|
|
4465
4745
|
await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));
|
|
4466
4746
|
}
|
|
4467
4747
|
async fetchPinnedMessages(channelId) {
|
|
4468
|
-
const data = await this.#rest.get(Routes.
|
|
4469
|
-
return data.map((item) => this.messages(channelId).upsert(item));
|
|
4748
|
+
const data = await this.#rest.get(Routes.channelMessagesPins(channelId));
|
|
4749
|
+
return data.items.map((item) => this.messages(channelId).upsert(item.message));
|
|
4470
4750
|
}
|
|
4471
|
-
async pinMessage(channelId, messageId) {
|
|
4472
|
-
await this.#rest.put(Routes.
|
|
4751
|
+
async pinMessage(channelId, messageId, reason) {
|
|
4752
|
+
await this.#rest.put(Routes.channelMessagesPin(channelId, messageId), undefined, { reason });
|
|
4473
4753
|
}
|
|
4474
|
-
async unpinMessage(channelId, messageId) {
|
|
4475
|
-
await this.#rest.delete(Routes.
|
|
4754
|
+
async unpinMessage(channelId, messageId, reason) {
|
|
4755
|
+
await this.#rest.delete(Routes.channelMessagesPin(channelId, messageId), { reason });
|
|
4756
|
+
}
|
|
4757
|
+
async createWebhook(channelId, options) {
|
|
4758
|
+
const [payload, reason] = splitReason(options);
|
|
4759
|
+
return this.#rest.post(Routes.channelWebhooks(channelId), payload, {
|
|
4760
|
+
reason
|
|
4761
|
+
});
|
|
4476
4762
|
}
|
|
4477
4763
|
createThreadFromMessage(channelId, messageId, options) {
|
|
4478
4764
|
return this.threads(channelId).createFromMessage(messageId, options);
|
|
@@ -4490,7 +4776,7 @@ class ChannelManager extends Manager {
|
|
|
4490
4776
|
hasMore: messages.length === limit
|
|
4491
4777
|
};
|
|
4492
4778
|
}
|
|
4493
|
-
|
|
4779
|
+
bulkDelete(channelId, messageIds) {
|
|
4494
4780
|
return this.bulkDeleteMessages(channelId, messageIds);
|
|
4495
4781
|
}
|
|
4496
4782
|
clear() {
|
|
@@ -4576,7 +4862,26 @@ class GatewaySession {
|
|
|
4576
4862
|
return resume ? { type: "resume", ...resume } : { type: "identify" };
|
|
4577
4863
|
}
|
|
4578
4864
|
connectURL(fallback) {
|
|
4579
|
-
|
|
4865
|
+
const resume = this.resumeInfo()?.resumeURL;
|
|
4866
|
+
return resume !== undefined && isTrustedGatewayURL(resume, fallback) ? resume : fallback;
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
function isTrustedGatewayURL(url, fallback) {
|
|
4870
|
+
let parsed;
|
|
4871
|
+
try {
|
|
4872
|
+
parsed = new URL(url);
|
|
4873
|
+
} catch {
|
|
4874
|
+
return false;
|
|
4875
|
+
}
|
|
4876
|
+
if (parsed.protocol !== "wss:" || parsed.username || parsed.password)
|
|
4877
|
+
return false;
|
|
4878
|
+
const host = parsed.hostname.toLowerCase();
|
|
4879
|
+
if (host === "discord.gg" || host.endsWith(".discord.gg"))
|
|
4880
|
+
return true;
|
|
4881
|
+
try {
|
|
4882
|
+
return host === new URL(fallback).hostname.toLowerCase();
|
|
4883
|
+
} catch {
|
|
4884
|
+
return false;
|
|
4580
4885
|
}
|
|
4581
4886
|
}
|
|
4582
4887
|
|
|
@@ -4852,12 +5157,15 @@ class PlainTextDecoder {
|
|
|
4852
5157
|
|
|
4853
5158
|
class ZlibStreamDecoder {
|
|
4854
5159
|
#create;
|
|
5160
|
+
#maxFrameBytes;
|
|
4855
5161
|
#inflate;
|
|
4856
5162
|
#chunks = [];
|
|
5163
|
+
#size = 0;
|
|
4857
5164
|
#failure;
|
|
4858
5165
|
#pendingReject;
|
|
4859
|
-
constructor(create = () => createInflate()) {
|
|
5166
|
+
constructor(create = () => createInflate(), maxFrameBytes = 64 * 1024 * 1024) {
|
|
4860
5167
|
this.#create = create;
|
|
5168
|
+
this.#maxFrameBytes = maxFrameBytes;
|
|
4861
5169
|
}
|
|
4862
5170
|
push(data) {
|
|
4863
5171
|
if (typeof data === "string")
|
|
@@ -4876,6 +5184,7 @@ class ZlibStreamDecoder {
|
|
|
4876
5184
|
await this.#awaiting((settle) => inflate.flush(zlibConstants.Z_SYNC_FLUSH, () => settle()));
|
|
4877
5185
|
const parts = this.#chunks;
|
|
4878
5186
|
this.#chunks = [];
|
|
5187
|
+
this.#size = 0;
|
|
4879
5188
|
if (parts.length === 0)
|
|
4880
5189
|
return [];
|
|
4881
5190
|
const total = parts.reduce((size, part) => size + part.length, 0);
|
|
@@ -4891,6 +5200,7 @@ class ZlibStreamDecoder {
|
|
|
4891
5200
|
const inflate = this.#inflate;
|
|
4892
5201
|
this.#inflate = undefined;
|
|
4893
5202
|
this.#chunks = [];
|
|
5203
|
+
this.#size = 0;
|
|
4894
5204
|
this.#failure = undefined;
|
|
4895
5205
|
this.#pendingReject = undefined;
|
|
4896
5206
|
if (!inflate)
|
|
@@ -4918,7 +5228,17 @@ class ZlibStreamDecoder {
|
|
|
4918
5228
|
}
|
|
4919
5229
|
#open() {
|
|
4920
5230
|
const inflate = this.#create();
|
|
4921
|
-
inflate.on("data", (chunk) =>
|
|
5231
|
+
inflate.on("data", (chunk) => {
|
|
5232
|
+
if (this.#failure)
|
|
5233
|
+
return;
|
|
5234
|
+
this.#size += chunk.length;
|
|
5235
|
+
if (this.#size > this.#maxFrameBytes) {
|
|
5236
|
+
this.#chunks = [];
|
|
5237
|
+
inflate.emit("error", new Error(`Gateway frame inflated past ${this.#maxFrameBytes} bytes.`));
|
|
5238
|
+
return;
|
|
5239
|
+
}
|
|
5240
|
+
this.#chunks.push(chunk);
|
|
5241
|
+
});
|
|
4922
5242
|
inflate.on("error", (error) => {
|
|
4923
5243
|
this.#failure = error;
|
|
4924
5244
|
const reject = this.#pendingReject;
|
|
@@ -5161,9 +5481,9 @@ function classifyPayload(payload) {
|
|
|
5161
5481
|
}
|
|
5162
5482
|
function identifyPayload(options) {
|
|
5163
5483
|
const props = options.properties ?? {};
|
|
5164
|
-
const os = props.os ??
|
|
5165
|
-
const browser = props.browser ?? "
|
|
5166
|
-
const device = props.device ?? "
|
|
5484
|
+
const os = props.os ?? process.platform;
|
|
5485
|
+
const browser = props.browser ?? "Lunibee";
|
|
5486
|
+
const device = props.device ?? "Lunibee";
|
|
5167
5487
|
return {
|
|
5168
5488
|
op: GatewayOpcodes.Identify,
|
|
5169
5489
|
d: {
|
|
@@ -5268,9 +5588,9 @@ class Gateway {
|
|
|
5268
5588
|
heartbeatAckTimeout: 1e4,
|
|
5269
5589
|
zombieTimeout: 30000,
|
|
5270
5590
|
properties: {
|
|
5271
|
-
os:
|
|
5272
|
-
browser: "
|
|
5273
|
-
device: "
|
|
5591
|
+
os: process.platform,
|
|
5592
|
+
browser: "Lunibee",
|
|
5593
|
+
device: "Lunibee"
|
|
5274
5594
|
},
|
|
5275
5595
|
presence: {
|
|
5276
5596
|
status: "online",
|
|
@@ -5586,14 +5906,12 @@ class Gateway {
|
|
|
5586
5906
|
|
|
5587
5907
|
// packages/core/src/index.ts
|
|
5588
5908
|
class EventEmitter2 {
|
|
5589
|
-
#listeners =
|
|
5909
|
+
#listeners = {};
|
|
5910
|
+
redactSecrets = (text) => text;
|
|
5590
5911
|
on(event, listener) {
|
|
5591
5912
|
if (typeof listener !== "function")
|
|
5592
5913
|
throw new TypeError("Event listener must be a function.");
|
|
5593
|
-
|
|
5594
|
-
if (!listeners)
|
|
5595
|
-
this.#listeners.set(event, listeners = new Set);
|
|
5596
|
-
listeners.add(listener);
|
|
5914
|
+
(this.#listeners[event] ??= new Set).add(listener);
|
|
5597
5915
|
return this;
|
|
5598
5916
|
}
|
|
5599
5917
|
once(event, listener) {
|
|
@@ -5604,7 +5922,7 @@ class EventEmitter2 {
|
|
|
5604
5922
|
return this.on(event, wrapped);
|
|
5605
5923
|
}
|
|
5606
5924
|
off(event, listener) {
|
|
5607
|
-
this.#listeners
|
|
5925
|
+
this.#listeners[event]?.delete(listener);
|
|
5608
5926
|
return this;
|
|
5609
5927
|
}
|
|
5610
5928
|
removeListener(event, listener) {
|
|
@@ -5612,13 +5930,13 @@ class EventEmitter2 {
|
|
|
5612
5930
|
}
|
|
5613
5931
|
removeAllListeners(event) {
|
|
5614
5932
|
if (event === undefined)
|
|
5615
|
-
this.#listeners
|
|
5933
|
+
this.#listeners = {};
|
|
5616
5934
|
else
|
|
5617
|
-
this.#listeners
|
|
5935
|
+
delete this.#listeners[event];
|
|
5618
5936
|
return this;
|
|
5619
5937
|
}
|
|
5620
5938
|
emit(event, ...args) {
|
|
5621
|
-
const listeners = this.#listeners
|
|
5939
|
+
const listeners = this.#listeners[event];
|
|
5622
5940
|
if (!listeners?.size)
|
|
5623
5941
|
return false;
|
|
5624
5942
|
for (const listener of [...listeners]) {
|
|
@@ -5633,18 +5951,30 @@ class EventEmitter2 {
|
|
|
5633
5951
|
return true;
|
|
5634
5952
|
}
|
|
5635
5953
|
#handleError(event, error) {
|
|
5636
|
-
if (event === "error" /* Error */)
|
|
5637
|
-
return;
|
|
5638
5954
|
const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5955
|
+
const errorListeners = this.#listeners["error" /* Error */];
|
|
5956
|
+
const listeners = event === "error" /* Error */ ? [] : [...errorListeners ?? []];
|
|
5957
|
+
if (listeners.length === 0)
|
|
5958
|
+
return warnListenerError(event, normalized, this.redactSecrets);
|
|
5959
|
+
for (const listener of listeners) {
|
|
5642
5960
|
try {
|
|
5643
|
-
listener(normalized);
|
|
5644
|
-
|
|
5961
|
+
const result = listener(normalized);
|
|
5962
|
+
if (result && typeof result.then === "function")
|
|
5963
|
+
Promise.resolve(result).catch((failure) => warnListenerError("error" /* Error */, failure, this.redactSecrets));
|
|
5964
|
+
} catch (failure) {
|
|
5965
|
+
warnListenerError("error" /* Error */, failure, this.redactSecrets);
|
|
5966
|
+
}
|
|
5645
5967
|
}
|
|
5646
5968
|
}
|
|
5647
5969
|
}
|
|
5970
|
+
function warnListenerError(event, error, redact = (text) => text) {
|
|
5971
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
5972
|
+
process.emitWarning(redact(`A "${String(event)}" listener threw and no error listener handled it: ${failure.message}`), {
|
|
5973
|
+
type: "LunibeeWarning",
|
|
5974
|
+
code: "LUNIBEE_UNHANDLED_LISTENER_ERROR",
|
|
5975
|
+
detail: failure.stack === undefined ? undefined : redact(failure.stack)
|
|
5976
|
+
});
|
|
5977
|
+
}
|
|
5648
5978
|
|
|
5649
5979
|
class Client extends EventEmitter2 {
|
|
5650
5980
|
options;
|
|
@@ -5664,6 +5994,10 @@ class Client extends EventEmitter2 {
|
|
|
5664
5994
|
user;
|
|
5665
5995
|
readyAt;
|
|
5666
5996
|
state = "idle";
|
|
5997
|
+
redactSecrets = (text) => {
|
|
5998
|
+
const token = this.options.token;
|
|
5999
|
+
return token && token.length >= 8 ? text.split(token).join("[token]") : text;
|
|
6000
|
+
};
|
|
5667
6001
|
get token() {
|
|
5668
6002
|
return this.state === "destroyed" ? null : this.options.token ?? null;
|
|
5669
6003
|
}
|
|
@@ -5710,21 +6044,36 @@ class Client extends EventEmitter2 {
|
|
|
5710
6044
|
this.stageInstances = new StageInstanceManager(this.rest);
|
|
5711
6045
|
const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
|
|
5712
6046
|
this.application = { commands: placeholderAppCommands };
|
|
5713
|
-
this.#resourceContext =
|
|
6047
|
+
this.#resourceContext = this.#createResourceContext();
|
|
6048
|
+
this.guilds.attachContext(this.#resourceContext);
|
|
6049
|
+
this.#gateway = new Gateway({
|
|
6050
|
+
token: options.token,
|
|
6051
|
+
intents: options.intents,
|
|
6052
|
+
...options.gateway
|
|
6053
|
+
});
|
|
6054
|
+
this.#wireLifecycle();
|
|
6055
|
+
this.#wireMessages();
|
|
6056
|
+
this.#wireGuilds();
|
|
6057
|
+
this.#wireGuildFeatures();
|
|
6058
|
+
this.#wireChannels();
|
|
6059
|
+
this.#wireMisc();
|
|
6060
|
+
}
|
|
6061
|
+
#createResourceContext() {
|
|
6062
|
+
return {
|
|
5714
6063
|
sendMessage: (channelId, options) => this.channels.send(channelId, options),
|
|
5715
6064
|
editMessage: (channelId, messageId, options) => this.channels.editMessage(channelId, messageId, options),
|
|
5716
|
-
deleteMessage: (channelId, messageId) => this.channels.deleteMessage(channelId, messageId),
|
|
6065
|
+
deleteMessage: (channelId, messageId, reason) => this.channels.deleteMessage(channelId, messageId, reason),
|
|
5717
6066
|
crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId),
|
|
5718
6067
|
editChannel: (channelId, options) => this.channels.edit(channelId, options),
|
|
5719
|
-
deleteChannel: (channelId) => this.channels.
|
|
6068
|
+
deleteChannel: (channelId, reason) => this.channels.remove(channelId, reason),
|
|
5720
6069
|
addReaction: (channelId, messageId, emoji) => this.channels.addReaction(channelId, messageId, emoji),
|
|
5721
6070
|
removeOwnReaction: (channelId, messageId, emoji) => this.channels.removeOwnReaction(channelId, messageId, emoji),
|
|
5722
6071
|
removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
|
|
5723
6072
|
removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
|
|
5724
|
-
pinMessage: (channelId, messageId) => this.channels.pinMessage(channelId, messageId),
|
|
5725
|
-
unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId),
|
|
6073
|
+
pinMessage: (channelId, messageId, reason) => this.channels.pinMessage(channelId, messageId, reason),
|
|
6074
|
+
unpinMessage: (channelId, messageId, reason) => this.channels.unpinMessage(channelId, messageId, reason),
|
|
5726
6075
|
collectInteractions: (options) => this.createCollector("interactionCreate" /* InteractionCreate */, options),
|
|
5727
|
-
memberPermissions: (guildId, memberId, roleIds, channelId) => this.#memberPermissions(guildId, memberId, roleIds, channelId),
|
|
6076
|
+
memberPermissions: (guildId, memberId, roleIds, channelId, timedOutUntil) => this.#memberPermissions(guildId, memberId, roleIds, channelId, timedOutUntil),
|
|
5728
6077
|
kickMember: (guildId, userId, reason) => this.guilds.members(guildId).kick(userId, reason),
|
|
5729
6078
|
banMember: (guildId, userId, options) => this.guilds.members(guildId).ban(userId, options),
|
|
5730
6079
|
editMember: (guildId, userId, options, reason) => this.guilds.members(guildId).edit(userId, options, reason),
|
|
@@ -5747,12 +6096,8 @@ class Client extends EventEmitter2 {
|
|
|
5747
6096
|
return this.channels.permissionOverwrites(channelId).update(targetId, bits, options);
|
|
5748
6097
|
}
|
|
5749
6098
|
};
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
token: options.token,
|
|
5753
|
-
intents: options.intents,
|
|
5754
|
-
...options.gateway
|
|
5755
|
-
});
|
|
6099
|
+
}
|
|
6100
|
+
#wireLifecycle() {
|
|
5756
6101
|
this.#gateway.on("READY", (data) => {
|
|
5757
6102
|
const ready = data;
|
|
5758
6103
|
this.user = ready.user;
|
|
@@ -5778,6 +6123,8 @@ class Client extends EventEmitter2 {
|
|
|
5778
6123
|
this.state = "idle";
|
|
5779
6124
|
this.emit("close" /* Close */, data);
|
|
5780
6125
|
});
|
|
6126
|
+
}
|
|
6127
|
+
#wireMessages() {
|
|
5781
6128
|
this.#gateway.on("MESSAGE_CREATE", (data) => {
|
|
5782
6129
|
const payload = data;
|
|
5783
6130
|
const message = new Message(payload, this.#resourceContext);
|
|
@@ -5825,6 +6172,8 @@ class Client extends EventEmitter2 {
|
|
|
5825
6172
|
this.#gateway.on("MESSAGE_REACTION_REMOVE_EMOJI", (data) => this.emit("messageReactionRemoveEmoji" /* MessageReactionRemoveEmoji */, data));
|
|
5826
6173
|
this.#gateway.on("MESSAGE_POLL_VOTE_ADD", (data) => this.emit("messagePollVoteAdd" /* MessagePollVoteAdd */, data));
|
|
5827
6174
|
this.#gateway.on("MESSAGE_POLL_VOTE_REMOVE", (data) => this.emit("messagePollVoteRemove" /* MessagePollVoteRemove */, data));
|
|
6175
|
+
}
|
|
6176
|
+
#wireGuilds() {
|
|
5828
6177
|
this.#gateway.on("GUILD_CREATE", (data) => {
|
|
5829
6178
|
const payload = data;
|
|
5830
6179
|
if (payload.unavailable) {
|
|
@@ -5925,6 +6274,8 @@ class Client extends EventEmitter2 {
|
|
|
5925
6274
|
roles.delete(event.role_id);
|
|
5926
6275
|
this.emit("guildRoleDelete" /* GuildRoleDelete */, event, removed);
|
|
5927
6276
|
});
|
|
6277
|
+
}
|
|
6278
|
+
#wireGuildFeatures() {
|
|
5928
6279
|
this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
|
|
5929
6280
|
const event = data;
|
|
5930
6281
|
let previous = null;
|
|
@@ -6021,6 +6372,8 @@ class Client extends EventEmitter2 {
|
|
|
6021
6372
|
this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
|
|
6022
6373
|
});
|
|
6023
6374
|
this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
|
|
6375
|
+
}
|
|
6376
|
+
#wireChannels() {
|
|
6024
6377
|
this.#gateway.on("CHANNEL_CREATE", (data) => {
|
|
6025
6378
|
const channel = this.channels.upsert(data);
|
|
6026
6379
|
this.emit("channelCreate" /* ChannelCreate */, channel);
|
|
@@ -6088,6 +6441,8 @@ class Client extends EventEmitter2 {
|
|
|
6088
6441
|
this.emit("inviteDelete" /* InviteDelete */, invite);
|
|
6089
6442
|
});
|
|
6090
6443
|
this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
|
|
6444
|
+
}
|
|
6445
|
+
#wireMisc() {
|
|
6091
6446
|
this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
|
|
6092
6447
|
const state = data;
|
|
6093
6448
|
if (state.guild_id)
|
|
@@ -6163,7 +6518,7 @@ class Client extends EventEmitter2 {
|
|
|
6163
6518
|
get resourceContext() {
|
|
6164
6519
|
return this.#resourceContext;
|
|
6165
6520
|
}
|
|
6166
|
-
#memberPermissions(guildId, memberId, roleIds, channelId) {
|
|
6521
|
+
#memberPermissions(guildId, memberId, roleIds, channelId, timedOutUntil) {
|
|
6167
6522
|
const guild = this.guilds.get(guildId);
|
|
6168
6523
|
if (!guild)
|
|
6169
6524
|
return null;
|
|
@@ -6180,7 +6535,8 @@ class Client extends EventEmitter2 {
|
|
|
6180
6535
|
memberId,
|
|
6181
6536
|
memberRoleIds: [...roleIds],
|
|
6182
6537
|
roles: this.guilds.roles(guildId).values(),
|
|
6183
|
-
overwrites: channel?.permissionOverwrites
|
|
6538
|
+
overwrites: channel?.permissionOverwrites,
|
|
6539
|
+
timedOutUntil
|
|
6184
6540
|
});
|
|
6185
6541
|
}
|
|
6186
6542
|
permissionsFor(memberId, guildOrChannelId) {
|
|
@@ -6201,7 +6557,8 @@ class Client extends EventEmitter2 {
|
|
|
6201
6557
|
memberId,
|
|
6202
6558
|
memberRoleIds: member.roleIds,
|
|
6203
6559
|
roles: this.guilds.roles(guildId).values(),
|
|
6204
|
-
overwrites: channel?.permissionOverwrites
|
|
6560
|
+
overwrites: channel?.permissionOverwrites,
|
|
6561
|
+
timedOutUntil: member.timedOutUntil
|
|
6205
6562
|
});
|
|
6206
6563
|
}
|
|
6207
6564
|
fetchDefaultSoundboardSounds() {
|
|
@@ -6249,10 +6606,10 @@ class Client extends EventEmitter2 {
|
|
|
6249
6606
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
6250
6607
|
return this.rest.delete(Routes.interactionOriginalResponse(this.user.id, token));
|
|
6251
6608
|
}
|
|
6252
|
-
followUpInteraction(token, data) {
|
|
6609
|
+
async followUpInteraction(token, data) {
|
|
6253
6610
|
if (!this.user)
|
|
6254
6611
|
return Promise.reject(new Error("Client is unauthenticated."));
|
|
6255
|
-
return this.rest.post(
|
|
6612
|
+
return this.rest.post(Routes.webhook(this.user.id, token), toRequest(data, this.options.allowedMentions));
|
|
6256
6613
|
}
|
|
6257
6614
|
interactionWebhookMessage(method, applicationId, token, messageId, data) {
|
|
6258
6615
|
const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
|
|
@@ -6262,11 +6619,11 @@ class Client extends EventEmitter2 {
|
|
|
6262
6619
|
return this.rest.patch(path, data ? toRequest(data, this.options.allowedMentions) : data);
|
|
6263
6620
|
return this.rest.delete(path);
|
|
6264
6621
|
}
|
|
6265
|
-
fetchWebhook(id, token) {
|
|
6266
|
-
return this.rest.get(
|
|
6622
|
+
async fetchWebhook(id, token) {
|
|
6623
|
+
return this.rest.get(Routes.webhook(id, token));
|
|
6267
6624
|
}
|
|
6268
|
-
fetchGuildPreview(guildId) {
|
|
6269
|
-
return this.rest.get(
|
|
6625
|
+
async fetchGuildPreview(guildId) {
|
|
6626
|
+
return this.rest.get(Routes.guildPreview(guildId));
|
|
6270
6627
|
}
|
|
6271
6628
|
fetchVoiceRegions() {
|
|
6272
6629
|
return this.rest.get("/voice/regions");
|
|
@@ -6275,15 +6632,13 @@ class Client extends EventEmitter2 {
|
|
|
6275
6632
|
const query = new URLSearchParams;
|
|
6276
6633
|
if (options?.withCounts)
|
|
6277
6634
|
query.set("with_counts", "true");
|
|
6278
|
-
if (options?.withExpiration)
|
|
6279
|
-
query.set("with_expiration", "true");
|
|
6280
6635
|
if (options?.guildScheduledEventId)
|
|
6281
6636
|
query.set("guild_scheduled_event_id", options.guildScheduledEventId);
|
|
6282
6637
|
const qs = query.toString();
|
|
6283
6638
|
return this.rest.get(`/invites/${encodeURIComponent(code)}${qs ? `?${qs}` : ""}`);
|
|
6284
6639
|
}
|
|
6285
|
-
fetchSticker(id) {
|
|
6286
|
-
return this.rest.get(
|
|
6640
|
+
async fetchSticker(id) {
|
|
6641
|
+
return this.rest.get(Routes.sticker(id));
|
|
6287
6642
|
}
|
|
6288
6643
|
fetchPremiumStickerPacks() {
|
|
6289
6644
|
return this.rest.get(`/sticker-packs`);
|
|
@@ -6324,4 +6679,4 @@ export {
|
|
|
6324
6679
|
resolveGatewayIntents
|
|
6325
6680
|
};
|
|
6326
6681
|
|
|
6327
|
-
//# debugId=
|
|
6682
|
+
//# debugId=9FDCE9C1C9B0DB0164756E2164756E21
|