@openclaw/discord 2026.7.2-beta.7 → 2026.8.1-beta.3
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/dist/{account-inspect-SXiCBCgP.js → account-inspect-D5xmUpnj.js} +49 -43
- package/dist/account-inspect-api.js +1 -1
- package/dist/accounts-DNl-oCEw.js +371 -0
- package/dist/action-runtime-api.js +1 -1
- package/dist/{active-turn-thread-route-MlKWp8RD.js → active-turn-thread-route-fmHl1HNd.js} +9 -11
- package/dist/{activities-api-DTKsuDxf.js → activities-api-KCBAmWxD.js} +133 -175
- package/dist/activities-api.js +1 -1
- package/dist/{allow-list-DzKrtfah.js → allow-list-BDMimASD.js} +2 -3
- package/dist/{api-DnrK9gML.js → api-DNVbJyEy.js} +7 -2
- package/dist/api.js +18 -18
- package/dist/{approval-handler.runtime-HymvFTYn.js → approval-handler.runtime-B12RCYr8.js} +6 -6
- package/dist/{approval-message-safety-DEyKVsAw.js → approval-message-safety-XGFPbDoI.js} +89 -3
- package/dist/{audit-CjsrabP8.js → audit-Yc7eZDd6.js} +5 -5
- package/dist/{channel-actions-uXFTJX3o.js → channel-actions-Dr2QI8Bf.js} +11 -7
- package/dist/{channel-actions.runtime-CIYU90sl.js → channel-actions.runtime-CODTvo7c.js} +99 -97
- package/dist/{channel-vKa-76xY.js → channel-cXYzGc4L.js} +102 -104
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-CmcwZ_qd.js → channel.setup-CSiwnMgs.js} +16 -54
- package/dist/{outbound-session-route-H-HoyH5U.js → components-ezGKo_Yh.js} +69 -142
- package/dist/{config-schema-WHRQcY19.js → config-schema-DC5kDtQ5.js} +42 -11
- package/dist/conversation-binding-route-D6rCQ5S0.js +43 -0
- package/dist/{directory-config-D_LojtCe.js → directory-config-XyCfoqLg.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-Bw5Ephzv.js → directory-live-Df0NbFJB.js} +7 -4
- package/dist/{doctor-Bc4S1qyd.js → doctor-DYY31GrO.js} +34 -13
- package/dist/{doctor-contract-CCFMIDk9.js → doctor-contract-DsWvKIXF.js} +2 -3
- package/dist/doctor-contract-api.js +147 -2
- package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-6Tvvinsa.js} +4 -7
- package/dist/{inbound-event-delivery-CEPlt2uz.js → inbound-event-delivery-De2qxTrP.js} +4 -25
- package/dist/index.js +5 -4
- package/dist/{message-handler-CeiSulIw.js → message-handler-B61q5MOF.js} +118 -33
- package/dist/{message-handler.preflight-DibgQFf2.js → message-handler.preflight-Bzg_Hawz.js} +75 -61
- package/dist/{message-handler.process-Dnc_oz9y.js → message-handler.process--4_712Ec.js} +236 -296
- package/dist/{message-utils-BgTwT_q7.js → message-utils-BXLLnFl6.js} +34 -35
- package/dist/{model-picker-preference-primitives-D25pnCOu.js → model-picker-preference-primitives-BHT1LkR_.js} +3 -3
- package/dist/{outbound-adapter-DtE-i2OJ.js → outbound-adapter-DxHTOqiN.js} +157 -68
- package/dist/{outbound-components-C7GVyfPh.js → outbound-components-B2PL0ooH.js} +3 -3
- package/dist/owner-access-Bg41VzAf.js +107 -0
- package/dist/{pluralkit-CD4B11JB.js → pluralkit-dUl4v1X3.js} +1 -1
- package/dist/{preflight-audio-BjnQZ5yS.js → preflight-audio-DrnqFA8U.js} +22 -28
- package/dist/{probe-BeWKhjqX.js → probe-BTdtVRwU.js} +37 -13
- package/dist/probe.runtime-Dq5-PRKT.js +2 -0
- package/dist/{provider-DfQJX3z5.js → provider-DlK_ynqt.js} +1131 -2021
- package/dist/{provider-session.runtime-Bo88k0pV.js → provider-session.runtime-CvvphHvs.js} +3 -3
- package/dist/provider.runtime-CzKGRiAF.js +2 -0
- package/dist/realtime-session.runtime-ysbMG8v7.js +1351 -0
- package/dist/{resolve-allowlist-common-DHERApxi.js → resolve-allowlist-common-DIVXbD1P.js} +3 -3
- package/dist/{resolve-channels-BjepAj8b.js → resolve-channels-CGeUoIqb.js} +4 -4
- package/dist/{resolve-users-Bc28htgt.js → resolve-users-BtKxLUZv.js} +3 -3
- package/dist/{chunk-DX4jpFQP.js → retry-DNsVTeTo.js} +308 -131
- package/dist/{runtime-BmW_j_hl.js → runtime-CQovMsH3.js} +12 -15
- package/dist/{runtime-_aRC6V2s.js → runtime-D71_VFLr.js} +49 -58
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +23 -23
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-CzeTYF32.js +6 -0
- package/dist/runtime-api.monitor.js +6 -5
- package/dist/runtime-api.send.js +6 -6
- package/dist/runtime-api.threads.js +5 -6
- package/dist/sdk-runtime-37OU6_Yh.js +369 -0
- package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
- package/dist/{send-CdkZ6zeW.js → send-rQIffSYu.js} +180 -91
- package/dist/{send.components-5uqwkjgE.js → send.components-ChK1wS7w.js} +32 -46
- package/dist/{send.outbound-D-80Ej-t.js → send.outbound-HIkgji_7.js} +57 -34
- package/dist/{send.reactions-CtlmGd_o.js → send.reactions-gmJ6yFPo.js} +14 -21
- package/dist/{send.receipt-CuwRrpFz.js → send.receipt-Cnhoautb.js} +29 -1
- package/dist/{send.shared-jpvAG_u6.js → send.shared-B3fpaLWJ.js} +112 -181
- package/dist/{sender-identity-mG_zsdox.js → sender-identity-BJtfyise.js} +1 -1
- package/dist/setup-entry.js +0 -5
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-CXF1tup1.js → shared-CaAaoksy.js} +27 -23
- package/dist/subagent-hooks-CNT2ZJTJ.js +49 -0
- package/dist/subagent-hooks-api.js +2 -6
- package/dist/subagent-progress-FPLqBY1s.js +110 -0
- package/dist/{system-events-DdUqf91B.js → system-events-Nuwoq_au.js} +2 -2
- package/dist/{target-resolver-C3s_2m0t.js → target-resolver-DIXShHaZ.js} +3 -3
- package/dist/targets-B2pf49zc.js +3 -0
- package/dist/{thread-bindings-C-M-ly7P.js → thread-bindings-VlymUnbz.js} +29 -28
- package/dist/{thread-bindings.manager-DYvSlrva.js → thread-bindings.manager-CngsgErq.js} +258 -29
- package/dist/{thread-bindings.session-updates-DAIlp7Px.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
- package/dist/{thread-bindings.state-Cgi5uRn-.js → thread-bindings.state-D8OMdk4O.js} +3 -16
- package/dist/threading-DU6pgeGm.js +456 -0
- package/dist/transcripts-source-DeIMNbRh.js +265 -0
- package/dist/transcripts-source-api.js +7 -2
- package/dist/{typing--Mzo2kM7.js → typing-oLiS5Z13.js} +1 -1
- package/dist/voice-runtime-CjNFaynA.js +2549 -0
- package/openclaw.plugin.json +215 -25
- package/package.json +15 -11
- package/skills/discord/SKILL.md +22 -115
- package/dist/accounts-DJTf1LtA.js +0 -219
- package/dist/channel-api-CAJ0wMoV.js +0 -21
- package/dist/legacy-state-migrations-api.js +0 -138
- package/dist/manager.runtime-Bjav3pfC.js +0 -3655
- package/dist/preflight-audio.runtime-CoCXMM8r.js +0 -7
- package/dist/probe.runtime-DqFGFMbZ.js +0 -2
- package/dist/provider.runtime-Cy7XZmyh.js +0 -2
- package/dist/runtime-api.monitor-CCRubd3-.js +0 -5
- package/dist/session-binding-contract-api.js +0 -2
- package/dist/subagent-hooks-Dxy7Fmnq.js +0 -120
- package/dist/subagent-progress-DI3sYLLo.js +0 -664
- package/dist/targets-Dv_RN7vT.js +0 -3
- package/dist/thread-bindings.discord-api-BoDNqamb.js +0 -246
- package/dist/transcripts-source-DIKGsTGT.js +0 -123
- package/node_modules/p-map/index.d.ts +0 -155
- package/node_modules/p-map/index.js +0 -285
- package/node_modules/p-map/license +0 -9
- package/node_modules/p-map/package.json +0 -57
- package/node_modules/p-map/readme.md +0 -190
- package/dist/{audit-core-xwjIczO0.js → audit-core-BCX8UeFH.js} +1 -1
- package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { t as parseDiscordRetryAfterBodySeconds } from "./retry-after-DdLPmPoa.js";
|
|
2
|
+
import { k as parseDiscordTarget } from "./accounts-DNl-oCEw.js";
|
|
2
3
|
import "node:module";
|
|
4
|
+
import { redactIdentifier, redactSensitiveFieldValue } from "openclaw/plugin-sdk/logging-core";
|
|
3
5
|
import { ApplicationCommandOptionType, ApplicationCommandType, ButtonStyle, ComponentType, GatewayDispatchEvents, InteractionContextType, InteractionResponseType, InteractionType, MessageFlags, Routes, TextInputStyle } from "discord-api-types/v10";
|
|
4
6
|
import { createHash } from "node:crypto";
|
|
5
|
-
import { asDateTimestampMs, clampTimerTimeoutMs,
|
|
7
|
+
import { asDateTimestampMs, clampTimerTimeoutMs, parseStrictNonNegativeInteger, resolveExpiresAtMsFromDurationMs, resolveIntegerOption, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
6
8
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
7
9
|
import { Type } from "typebox";
|
|
8
10
|
import { Check } from "typebox/value";
|
|
9
11
|
import { inspect } from "node:util";
|
|
10
12
|
import { gunzipSync } from "node:zlib";
|
|
11
13
|
import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
|
|
12
|
-
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
13
|
-
import { parseRetryAfterHeaderSeconds } from "openclaw/plugin-sdk/retry-runtime";
|
|
14
|
-
import {
|
|
14
|
+
import { collectErrorGraphCandidates, extractErrorCode, formatErrorMessage, readErrorName } from "openclaw/plugin-sdk/error-runtime";
|
|
15
|
+
import { classifyTransientNetworkErrorCode, createChannelApiRetryRunner, parseRetryAfterHeaderSeconds, resolveRetryConfig, retryAsync } from "openclaw/plugin-sdk/retry-runtime";
|
|
16
|
+
import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
15
17
|
import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
|
|
16
18
|
import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-chunking";
|
|
17
19
|
import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
|
|
@@ -402,6 +404,11 @@ function stableCommandSetHash(commands) {
|
|
|
402
404
|
return createHash("sha256").update(JSON.stringify(stable)).digest("hex");
|
|
403
405
|
}
|
|
404
406
|
//#endregion
|
|
407
|
+
//#region extensions/discord/src/internal/undefined-fields.ts
|
|
408
|
+
function stripUndefinedFields(value) {
|
|
409
|
+
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
410
|
+
}
|
|
411
|
+
//#endregion
|
|
405
412
|
//#region extensions/discord/src/internal/components.base.ts
|
|
406
413
|
function parseCustomId(id) {
|
|
407
414
|
const [rawKeyValue, ...parts] = id.split(";");
|
|
@@ -423,9 +430,6 @@ function parseCustomId(id) {
|
|
|
423
430
|
data
|
|
424
431
|
};
|
|
425
432
|
}
|
|
426
|
-
function clean$3(value) {
|
|
427
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
428
|
-
}
|
|
429
433
|
function colorToNumber(value) {
|
|
430
434
|
if (typeof value === "number") return Number.isInteger(value) && value >= 0 && value <= 16777215 ? value : void 0;
|
|
431
435
|
if (typeof value === "string" && /^#?[0-9a-f]{6}$/i.test(value)) return Number.parseInt(value.replace(/^#/, ""), 16);
|
|
@@ -458,7 +462,7 @@ var BaseButton = class extends BaseMessageInteractiveComponent {
|
|
|
458
462
|
};
|
|
459
463
|
var Button = class extends BaseButton {
|
|
460
464
|
serialize() {
|
|
461
|
-
return
|
|
465
|
+
return stripUndefinedFields({
|
|
462
466
|
type: this.type,
|
|
463
467
|
style: this.style,
|
|
464
468
|
custom_id: this.customId,
|
|
@@ -478,7 +482,7 @@ var LinkButton = class extends BaseButton {
|
|
|
478
482
|
throw new Error("Link buttons do not run handlers");
|
|
479
483
|
}
|
|
480
484
|
serialize() {
|
|
481
|
-
return
|
|
485
|
+
return stripUndefinedFields({
|
|
482
486
|
type: this.type,
|
|
483
487
|
style: this.style,
|
|
484
488
|
label: this.label,
|
|
@@ -494,7 +498,7 @@ var AnySelectMenu = class extends BaseMessageInteractiveComponent {
|
|
|
494
498
|
this.disabled = false;
|
|
495
499
|
}
|
|
496
500
|
serialize() {
|
|
497
|
-
return
|
|
501
|
+
return stripUndefinedFields({
|
|
498
502
|
...this.serializeOptions(),
|
|
499
503
|
custom_id: this.customId,
|
|
500
504
|
placeholder: this.placeholder,
|
|
@@ -591,7 +595,7 @@ var TextDisplay = class extends BaseComponent {
|
|
|
591
595
|
this.isV2 = true;
|
|
592
596
|
}
|
|
593
597
|
serialize() {
|
|
594
|
-
return
|
|
598
|
+
return stripUndefinedFields({
|
|
595
599
|
type: this.type,
|
|
596
600
|
content: this.content
|
|
597
601
|
});
|
|
@@ -608,7 +612,7 @@ var Separator = class extends BaseComponent {
|
|
|
608
612
|
this.divider = options?.divider ?? this.divider;
|
|
609
613
|
}
|
|
610
614
|
serialize() {
|
|
611
|
-
return
|
|
615
|
+
return stripUndefinedFields({
|
|
612
616
|
type: this.type,
|
|
613
617
|
divider: this.divider,
|
|
614
618
|
spacing: this.spacing === "large" ? 2 : this.spacing === "small" ? 1 : this.spacing
|
|
@@ -623,7 +627,7 @@ var Thumbnail = class extends BaseComponent {
|
|
|
623
627
|
this.isV2 = true;
|
|
624
628
|
}
|
|
625
629
|
serialize() {
|
|
626
|
-
return
|
|
630
|
+
return stripUndefinedFields({
|
|
627
631
|
type: this.type,
|
|
628
632
|
media: this.url ? { url: this.url } : void 0
|
|
629
633
|
});
|
|
@@ -638,7 +642,7 @@ var Section = class extends BaseComponent {
|
|
|
638
642
|
this.isV2 = true;
|
|
639
643
|
}
|
|
640
644
|
serialize() {
|
|
641
|
-
return
|
|
645
|
+
return stripUndefinedFields({
|
|
642
646
|
type: this.type,
|
|
643
647
|
components: this.components.map((entry) => entry.serialize()),
|
|
644
648
|
accessory: this.accessory?.serialize()
|
|
@@ -672,7 +676,7 @@ var File = class extends BaseComponent {
|
|
|
672
676
|
this.isV2 = true;
|
|
673
677
|
}
|
|
674
678
|
serialize() {
|
|
675
|
-
return
|
|
679
|
+
return stripUndefinedFields({
|
|
676
680
|
type: this.type,
|
|
677
681
|
file: this.file ? { url: this.file } : void 0,
|
|
678
682
|
spoiler: this.spoiler || void 0
|
|
@@ -690,7 +694,7 @@ var Container = class extends BaseComponent {
|
|
|
690
694
|
this.spoiler = options?.spoiler ?? false;
|
|
691
695
|
}
|
|
692
696
|
serialize() {
|
|
693
|
-
return
|
|
697
|
+
return stripUndefinedFields({
|
|
694
698
|
type: this.type,
|
|
695
699
|
components: this.components.map((entry) => entry.serialize()),
|
|
696
700
|
accent_color: colorToNumber(this.accentColor),
|
|
@@ -708,7 +712,7 @@ var TextInput = class extends BaseModalComponent {
|
|
|
708
712
|
this.style = TextInputStyle.Short;
|
|
709
713
|
}
|
|
710
714
|
serialize() {
|
|
711
|
-
return
|
|
715
|
+
return stripUndefinedFields({
|
|
712
716
|
type: this.type,
|
|
713
717
|
custom_id: this.customId,
|
|
714
718
|
style: this.style,
|
|
@@ -727,7 +731,7 @@ var CheckboxGroup = class extends BaseModalComponent {
|
|
|
727
731
|
this.options = [];
|
|
728
732
|
}
|
|
729
733
|
serialize() {
|
|
730
|
-
return
|
|
734
|
+
return stripUndefinedFields({
|
|
731
735
|
type: this.type,
|
|
732
736
|
custom_id: this.customId,
|
|
733
737
|
options: this.options,
|
|
@@ -744,7 +748,7 @@ var RadioGroup = class extends BaseModalComponent {
|
|
|
744
748
|
this.options = [];
|
|
745
749
|
}
|
|
746
750
|
serialize() {
|
|
747
|
-
return
|
|
751
|
+
return stripUndefinedFields({
|
|
748
752
|
type: this.type,
|
|
749
753
|
custom_id: this.customId,
|
|
750
754
|
options: this.options,
|
|
@@ -762,7 +766,7 @@ var Label = class extends BaseModalComponent {
|
|
|
762
766
|
this.customId = "";
|
|
763
767
|
}
|
|
764
768
|
serialize() {
|
|
765
|
-
return
|
|
769
|
+
return stripUndefinedFields({
|
|
766
770
|
type: this.type,
|
|
767
771
|
label: this.label,
|
|
768
772
|
description: this.description,
|
|
@@ -785,15 +789,12 @@ var Modal = class {
|
|
|
785
789
|
};
|
|
786
790
|
//#endregion
|
|
787
791
|
//#region extensions/discord/src/internal/embeds.ts
|
|
788
|
-
function clean$2(value) {
|
|
789
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
790
|
-
}
|
|
791
792
|
var Embed = class {
|
|
792
793
|
constructor(embed) {
|
|
793
794
|
Object.assign(this, embed);
|
|
794
795
|
}
|
|
795
796
|
serialize() {
|
|
796
|
-
return
|
|
797
|
+
return stripUndefinedFields({
|
|
797
798
|
title: this.title,
|
|
798
799
|
description: this.description,
|
|
799
800
|
url: this.url,
|
|
@@ -809,28 +810,22 @@ var Embed = class {
|
|
|
809
810
|
};
|
|
810
811
|
//#endregion
|
|
811
812
|
//#region extensions/discord/src/internal/payload.ts
|
|
812
|
-
function
|
|
813
|
-
return
|
|
814
|
-
}
|
|
815
|
-
function serializeAnyComponent(component) {
|
|
816
|
-
return component.serialize();
|
|
817
|
-
}
|
|
818
|
-
function payloadHasV2Components(payload) {
|
|
819
|
-
return Boolean(payload.components?.some((component) => component.isV2));
|
|
813
|
+
function hasDiscordV2Components(components) {
|
|
814
|
+
return Boolean(components?.some((component) => "isV2" in component && component.isV2 || "type" in component && component.type !== ComponentType.ActionRow));
|
|
820
815
|
}
|
|
821
816
|
function normalizePayloadFlags(payload) {
|
|
822
817
|
const flags = payload.ephemeral ? (payload.flags ?? 0) | MessageFlags.Ephemeral : payload.flags;
|
|
823
|
-
if (!
|
|
818
|
+
if (!hasDiscordV2Components(payload.components)) return flags;
|
|
824
819
|
if (payload.content || payload.embeds?.length) throw new Error("Discord Components V2 payloads cannot include content or embeds");
|
|
825
820
|
return (flags ?? 0) | MessageFlags.IsComponentsV2;
|
|
826
821
|
}
|
|
827
822
|
function serializePayload(payload) {
|
|
828
823
|
if (typeof payload === "string") return { content: payload };
|
|
829
824
|
const flags = normalizePayloadFlags(payload);
|
|
830
|
-
return
|
|
825
|
+
return stripUndefinedFields({
|
|
831
826
|
content: payload.content,
|
|
832
827
|
embeds: payload.embeds?.map((entry) => "serialize" in entry ? entry.serialize() : entry),
|
|
833
|
-
components: payload.components?.map((entry) =>
|
|
828
|
+
components: payload.components?.map((entry) => "serialize" in entry ? entry.serialize() : entry),
|
|
834
829
|
allowed_mentions: payload.allowed_mentions ?? payload.allowedMentions,
|
|
835
830
|
flags,
|
|
836
831
|
tts: payload.tts,
|
|
@@ -881,7 +876,7 @@ var ComponentRegistry = class {
|
|
|
881
876
|
clearTimeout(existing.timer);
|
|
882
877
|
existing.resolve({
|
|
883
878
|
success: false,
|
|
884
|
-
message,
|
|
879
|
+
message: existing.message,
|
|
885
880
|
reason: "timed out"
|
|
886
881
|
});
|
|
887
882
|
}
|
|
@@ -995,6 +990,12 @@ var Guild = class extends Base {
|
|
|
995
990
|
get name() {
|
|
996
991
|
return this.rawDataValue?.name ?? "";
|
|
997
992
|
}
|
|
993
|
+
get icon() {
|
|
994
|
+
return this.rawDataValue?.icon;
|
|
995
|
+
}
|
|
996
|
+
get iconUrl() {
|
|
997
|
+
return this.icon ? `https://cdn.discordapp.com/icons/${this.id}/${this.icon}.png` : null;
|
|
998
|
+
}
|
|
998
999
|
};
|
|
999
1000
|
var GuildMember = class extends Base {
|
|
1000
1001
|
constructor(client, rawData) {
|
|
@@ -1169,11 +1170,15 @@ var DiscordEntityCache = class {
|
|
|
1169
1170
|
const raw = data && typeof data === "object" ? data : {};
|
|
1170
1171
|
const channelUpdate = GatewayDispatchEvents.ChannelUpdate;
|
|
1171
1172
|
const channelDelete = GatewayDispatchEvents.ChannelDelete;
|
|
1173
|
+
const threadUpdate = GatewayDispatchEvents.ThreadUpdate;
|
|
1174
|
+
const threadDelete = GatewayDispatchEvents.ThreadDelete;
|
|
1172
1175
|
const guildUpdate = GatewayDispatchEvents.GuildUpdate;
|
|
1176
|
+
const guildMemberAdd = GatewayDispatchEvents.GuildMemberAdd;
|
|
1177
|
+
const guildMemberRemove = GatewayDispatchEvents.GuildMemberRemove;
|
|
1173
1178
|
const guildMemberUpdate = GatewayDispatchEvents.GuildMemberUpdate;
|
|
1174
|
-
if (type === channelUpdate || type === channelDelete) this.deleteId("channel", raw.id);
|
|
1179
|
+
if (type === channelUpdate || type === channelDelete || type === threadUpdate || type === threadDelete) this.deleteId("channel", raw.id);
|
|
1175
1180
|
if (type === guildUpdate) this.deleteId("guild", raw.id);
|
|
1176
|
-
if (type === guildMemberUpdate) {
|
|
1181
|
+
if (type === guildMemberAdd || type === guildMemberRemove || type === guildMemberUpdate) {
|
|
1177
1182
|
const guildId = raw.guild_id;
|
|
1178
1183
|
const user = raw.user && typeof raw.user === "object" ? raw.user : {};
|
|
1179
1184
|
if (typeof guildId === "string" && typeof user.id === "string") {
|
|
@@ -1360,9 +1365,6 @@ function isListenerTimeoutError(error) {
|
|
|
1360
1365
|
}
|
|
1361
1366
|
//#endregion
|
|
1362
1367
|
//#region extensions/discord/src/internal/commands.ts
|
|
1363
|
-
function clean(value) {
|
|
1364
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
1365
|
-
}
|
|
1366
1368
|
function resolveConditionalCommandOption(value, interaction) {
|
|
1367
1369
|
return typeof value === "function" ? value(interaction) : value;
|
|
1368
1370
|
}
|
|
@@ -1382,12 +1384,9 @@ function findCommandOption(options, name) {
|
|
|
1382
1384
|
if (!name) return;
|
|
1383
1385
|
return options?.find((option) => option.name === name);
|
|
1384
1386
|
}
|
|
1385
|
-
function hasCommandOptions(command) {
|
|
1386
|
-
return "options" in command;
|
|
1387
|
-
}
|
|
1388
1387
|
function resolveFocusedCommandOptionAutocompleteHandler(command, interaction) {
|
|
1389
1388
|
const focusedName = interaction.options.getFocused()?.name;
|
|
1390
|
-
const autocomplete = findCommandOption(
|
|
1389
|
+
const autocomplete = findCommandOption(command.commandKind === "group" ? findSelectedSubcommand(command.subcommands, interaction)?.options : command.options, focusedName)?.autocomplete;
|
|
1391
1390
|
return typeof autocomplete === "function" ? autocomplete : void 0;
|
|
1392
1391
|
}
|
|
1393
1392
|
var BaseCommand = class {
|
|
@@ -1402,7 +1401,7 @@ var BaseCommand = class {
|
|
|
1402
1401
|
];
|
|
1403
1402
|
}
|
|
1404
1403
|
serialize() {
|
|
1405
|
-
return
|
|
1404
|
+
return stripUndefinedFields({
|
|
1406
1405
|
name: this.name,
|
|
1407
1406
|
name_localizations: this.nameLocalizations,
|
|
1408
1407
|
description: this.type === ApplicationCommandType.ChatInput ? this.description ?? "" : void 0,
|
|
@@ -1418,6 +1417,7 @@ var BaseCommand = class {
|
|
|
1418
1417
|
var Command = class extends BaseCommand {
|
|
1419
1418
|
constructor(..._args) {
|
|
1420
1419
|
super(..._args);
|
|
1420
|
+
this.commandKind = "leaf";
|
|
1421
1421
|
this.type = ApplicationCommandType.ChatInput;
|
|
1422
1422
|
}
|
|
1423
1423
|
async autocomplete(interaction) {
|
|
@@ -1439,6 +1439,7 @@ var Command = class extends BaseCommand {
|
|
|
1439
1439
|
var CommandWithSubcommands = class extends BaseCommand {
|
|
1440
1440
|
constructor(..._args2) {
|
|
1441
1441
|
super(..._args2);
|
|
1442
|
+
this.commandKind = "group";
|
|
1442
1443
|
this.type = ApplicationCommandType.ChatInput;
|
|
1443
1444
|
}
|
|
1444
1445
|
async run(interaction) {
|
|
@@ -1451,7 +1452,7 @@ var CommandWithSubcommands = class extends BaseCommand {
|
|
|
1451
1452
|
return await subcommand.run(interaction);
|
|
1452
1453
|
}
|
|
1453
1454
|
serializeOptions() {
|
|
1454
|
-
return this.subcommands.map((command) =>
|
|
1455
|
+
return this.subcommands.map((command) => stripUndefinedFields({
|
|
1455
1456
|
name: command.name,
|
|
1456
1457
|
name_localizations: command.nameLocalizations,
|
|
1457
1458
|
description: command.description ?? "",
|
|
@@ -1660,6 +1661,7 @@ var BaseInteraction = class {
|
|
|
1660
1661
|
this.rawData = rawData;
|
|
1661
1662
|
this.message = null;
|
|
1662
1663
|
this.response = new InteractionResponseController();
|
|
1664
|
+
this.pendingResponse = Promise.resolve();
|
|
1663
1665
|
this.id = rawData.id;
|
|
1664
1666
|
this.token = rawData.token;
|
|
1665
1667
|
this.user = readInteractionUser(rawData, client);
|
|
@@ -1676,18 +1678,30 @@ var BaseInteraction = class {
|
|
|
1676
1678
|
set responseState(nextState) {
|
|
1677
1679
|
this.response.state = nextState;
|
|
1678
1680
|
}
|
|
1679
|
-
|
|
1680
|
-
this.
|
|
1681
|
-
|
|
1681
|
+
enqueueResponse(operation) {
|
|
1682
|
+
const result = this.pendingResponse.then(operation);
|
|
1683
|
+
this.pendingResponse = result.then(() => void 0, () => void 0);
|
|
1684
|
+
return result;
|
|
1685
|
+
}
|
|
1686
|
+
async performCallback(type, data) {
|
|
1687
|
+
if (this.response.acknowledged) throw new Error("Discord interaction has already been acknowledged.");
|
|
1688
|
+
const result = await createInteractionCallback(this.client.rest, this.id, this.token, data === void 0 ? { type } : {
|
|
1682
1689
|
type,
|
|
1683
1690
|
data
|
|
1684
1691
|
});
|
|
1692
|
+
this.response.recordCallback(type);
|
|
1693
|
+
return result;
|
|
1694
|
+
}
|
|
1695
|
+
async callback(type, data) {
|
|
1696
|
+
return await this.enqueueResponse(() => this.performCallback(type, data));
|
|
1685
1697
|
}
|
|
1686
1698
|
async reply(payload) {
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1699
|
+
return await this.enqueueResponse(async () => {
|
|
1700
|
+
const action = this.response.nextReplyAction();
|
|
1701
|
+
if (action === "edit") return await this.performReplyEdit(payload);
|
|
1702
|
+
if (action === "follow-up") return await this.performFollowUp(payload);
|
|
1703
|
+
return await this.performCallback(InteractionResponseType.ChannelMessageWithSource, serializePayload(payload));
|
|
1704
|
+
});
|
|
1691
1705
|
}
|
|
1692
1706
|
async defer(options) {
|
|
1693
1707
|
return await this.callback(InteractionResponseType.DeferredChannelMessageWithSource, options?.ephemeral ? { flags: 64 } : void 0);
|
|
@@ -1696,6 +1710,9 @@ var BaseInteraction = class {
|
|
|
1696
1710
|
return await this.defer();
|
|
1697
1711
|
}
|
|
1698
1712
|
async editReply(payload) {
|
|
1713
|
+
return await this.enqueueResponse(() => this.performReplyEdit(payload));
|
|
1714
|
+
}
|
|
1715
|
+
async performReplyEdit(payload) {
|
|
1699
1716
|
const body = serializePayload(payload);
|
|
1700
1717
|
const query = needsComponentsV2Query(body) ? { with_components: true } : void 0;
|
|
1701
1718
|
const result = query ? await editWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original", { body }, query) : await editWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original", { body });
|
|
@@ -1703,12 +1720,14 @@ var BaseInteraction = class {
|
|
|
1703
1720
|
return result;
|
|
1704
1721
|
}
|
|
1705
1722
|
async deleteReply() {
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1723
|
+
return await this.enqueueResponse(async () => {
|
|
1724
|
+
const result = await deleteWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original");
|
|
1725
|
+
this.response.recordReplyDelete();
|
|
1726
|
+
return result;
|
|
1727
|
+
});
|
|
1709
1728
|
}
|
|
1710
1729
|
async fetchReply() {
|
|
1711
|
-
return await getWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original");
|
|
1730
|
+
return await this.enqueueResponse(() => getWebhookMessage(this.client.rest, this.client.options.clientId, this.token, "@original"));
|
|
1712
1731
|
}
|
|
1713
1732
|
async replyAndWaitForComponent(payload, timeoutMs = 3e5) {
|
|
1714
1733
|
const result = await this.reply(payload);
|
|
@@ -1718,6 +1737,9 @@ var BaseInteraction = class {
|
|
|
1718
1737
|
return await this.client.componentHandler.waitForMessageComponent(message, timeoutMs);
|
|
1719
1738
|
}
|
|
1720
1739
|
async followUp(payload) {
|
|
1740
|
+
return await this.enqueueResponse(() => this.performFollowUp(payload));
|
|
1741
|
+
}
|
|
1742
|
+
async performFollowUp(payload) {
|
|
1721
1743
|
const body = serializePayload(payload);
|
|
1722
1744
|
return await createWebhookMessage(this.client.rest, this.client.options.clientId, this.token, { body }, needsComponentsV2Query(body) ? { with_components: true } : void 0);
|
|
1723
1745
|
}
|
|
@@ -1805,12 +1827,12 @@ async function dispatchInteraction(client, rawData) {
|
|
|
1805
1827
|
await optionAutocomplete(autocompleteInteraction);
|
|
1806
1828
|
return;
|
|
1807
1829
|
}
|
|
1808
|
-
if ("
|
|
1830
|
+
if (command.commandKind === "leaf") await command.autocomplete(autocompleteInteraction);
|
|
1809
1831
|
return;
|
|
1810
1832
|
}
|
|
1811
1833
|
if (rawData.type === InteractionType.ApplicationCommand) {
|
|
1812
1834
|
const command = client.commands.find((entry) => entry.name === readInteractionName(rawData));
|
|
1813
|
-
if (command
|
|
1835
|
+
if (command) {
|
|
1814
1836
|
await deferCommandInteractionIfNeeded(command, interaction);
|
|
1815
1837
|
await command.run(interaction);
|
|
1816
1838
|
}
|
|
@@ -1933,6 +1955,90 @@ function serializeRequestBody(data, headers) {
|
|
|
1933
1955
|
//#endregion
|
|
1934
1956
|
//#region extensions/discord/src/internal/rest-errors.ts
|
|
1935
1957
|
const DISCORD_UNKNOWN_VOICE_STATE = 10065;
|
|
1958
|
+
const DISCORD_ERROR_BODY_MAX_DEPTH = 64;
|
|
1959
|
+
const DISCORD_ERROR_BODY_MAX_NODES = 1e4;
|
|
1960
|
+
const DISCORD_ERROR_BODY_MAX_DEPTH_MARKER = "[Discord error body redacted: maximum depth exceeded]";
|
|
1961
|
+
const DISCORD_ERROR_BODY_MAX_NODES_MARKER = "[Discord error body redacted: node limit exceeded]";
|
|
1962
|
+
const DISCORD_ERROR_BODY_PRIORITY_KEYS = /* @__PURE__ */ new Set([
|
|
1963
|
+
"message",
|
|
1964
|
+
"code",
|
|
1965
|
+
"retry_after",
|
|
1966
|
+
"global"
|
|
1967
|
+
]);
|
|
1968
|
+
const DISCORD_RATE_LIMIT_SCOPES = /* @__PURE__ */ new Set([
|
|
1969
|
+
"user",
|
|
1970
|
+
"global",
|
|
1971
|
+
"shared"
|
|
1972
|
+
]);
|
|
1973
|
+
function isSensitiveDiscordErrorKey(key) {
|
|
1974
|
+
return redactSensitiveFieldValue(key, "") !== "";
|
|
1975
|
+
}
|
|
1976
|
+
function reserveRedactedKey(key, usedKeys, collisionCounts) {
|
|
1977
|
+
let count = (collisionCounts.get(key) ?? 0) + 1;
|
|
1978
|
+
let candidate = count === 1 ? key : `${key} [${count}]`;
|
|
1979
|
+
while (usedKeys.has(candidate)) {
|
|
1980
|
+
count += 1;
|
|
1981
|
+
candidate = `${key} [${count}]`;
|
|
1982
|
+
}
|
|
1983
|
+
collisionCounts.set(key, count);
|
|
1984
|
+
usedKeys.add(candidate);
|
|
1985
|
+
return candidate;
|
|
1986
|
+
}
|
|
1987
|
+
function redactDiscordErrorBody(body, fieldKey = "", sensitiveAncestorKey, state = {
|
|
1988
|
+
seen: /* @__PURE__ */ new WeakSet(),
|
|
1989
|
+
remainingNodes: DISCORD_ERROR_BODY_MAX_NODES
|
|
1990
|
+
}, depth = 0) {
|
|
1991
|
+
if (state.remainingNodes <= 0) return DISCORD_ERROR_BODY_MAX_NODES_MARKER;
|
|
1992
|
+
state.remainingNodes -= 1;
|
|
1993
|
+
if (typeof body === "string") return redactSensitiveFieldValue(sensitiveAncestorKey ?? fieldKey, body);
|
|
1994
|
+
if (sensitiveAncestorKey && (typeof body === "number" || typeof body === "boolean" || typeof body === "bigint")) return redactSensitiveFieldValue(sensitiveAncestorKey, String(body));
|
|
1995
|
+
if (!body || typeof body !== "object") return body;
|
|
1996
|
+
if (depth >= DISCORD_ERROR_BODY_MAX_DEPTH) return DISCORD_ERROR_BODY_MAX_DEPTH_MARKER;
|
|
1997
|
+
if (state.seen.has(body)) return "[Circular]";
|
|
1998
|
+
state.seen.add(body);
|
|
1999
|
+
let redacted;
|
|
2000
|
+
if (Array.isArray(body)) {
|
|
2001
|
+
const items = [];
|
|
2002
|
+
for (const entry of body) {
|
|
2003
|
+
if (state.remainingNodes <= 0) {
|
|
2004
|
+
items.push(DISCORD_ERROR_BODY_MAX_NODES_MARKER);
|
|
2005
|
+
break;
|
|
2006
|
+
}
|
|
2007
|
+
items.push(redactDiscordErrorBody(entry, fieldKey, sensitiveAncestorKey, state, depth + 1));
|
|
2008
|
+
}
|
|
2009
|
+
redacted = items;
|
|
2010
|
+
} else {
|
|
2011
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
2012
|
+
const collisionCounts = /* @__PURE__ */ new Map();
|
|
2013
|
+
const entries = [];
|
|
2014
|
+
const appendEntry = (nestedKey) => {
|
|
2015
|
+
if (state.remainingNodes <= 0) return false;
|
|
2016
|
+
const outputKey = reserveRedactedKey(redactSensitiveFieldValue(sensitiveAncestorKey ?? "", nestedKey), usedKeys, collisionCounts);
|
|
2017
|
+
const nestedSensitiveKey = isSensitiveDiscordErrorKey(nestedKey) ? nestedKey : sensitiveAncestorKey;
|
|
2018
|
+
entries.push([outputKey, redactDiscordErrorBody(body[nestedKey], nestedKey, nestedSensitiveKey, state, depth + 1)]);
|
|
2019
|
+
return true;
|
|
2020
|
+
};
|
|
2021
|
+
let truncated = false;
|
|
2022
|
+
for (const priorityKey of DISCORD_ERROR_BODY_PRIORITY_KEYS) if (Object.hasOwn(body, priorityKey) && !appendEntry(priorityKey)) {
|
|
2023
|
+
truncated = true;
|
|
2024
|
+
break;
|
|
2025
|
+
}
|
|
2026
|
+
if (!truncated) for (const nestedKey in body) {
|
|
2027
|
+
if (!Object.hasOwn(body, nestedKey) || DISCORD_ERROR_BODY_PRIORITY_KEYS.has(nestedKey)) continue;
|
|
2028
|
+
if (!appendEntry(nestedKey)) {
|
|
2029
|
+
truncated = true;
|
|
2030
|
+
break;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (truncated) {
|
|
2034
|
+
const markerKey = reserveRedactedKey(DISCORD_ERROR_BODY_MAX_NODES_MARKER, usedKeys, collisionCounts);
|
|
2035
|
+
entries.push([markerKey, DISCORD_ERROR_BODY_MAX_NODES_MARKER]);
|
|
2036
|
+
}
|
|
2037
|
+
redacted = Object.fromEntries(entries);
|
|
2038
|
+
}
|
|
2039
|
+
state.seen.delete(body);
|
|
2040
|
+
return redacted;
|
|
2041
|
+
}
|
|
1936
2042
|
function readDiscordCode(body) {
|
|
1937
2043
|
return parseStrictNonNegativeInteger(body && typeof body === "object" && "code" in body ? body.code : void 0);
|
|
1938
2044
|
}
|
|
@@ -1946,14 +2052,24 @@ function isUnknownDiscordVoiceStateError(err) {
|
|
|
1946
2052
|
function readRetryAfter(body, response, fallbackSeconds = 0) {
|
|
1947
2053
|
return parseDiscordRetryAfterBodySeconds(body && typeof body === "object" && "retry_after" in body ? body.retry_after : void 0) ?? parseRetryAfterHeaderSeconds(response.headers.get("Retry-After")) ?? fallbackSeconds;
|
|
1948
2054
|
}
|
|
2055
|
+
function readDiscordRateLimitBucket(response) {
|
|
2056
|
+
const value = response.headers.get("X-RateLimit-Bucket")?.trim();
|
|
2057
|
+
return value ? redactIdentifier(value, { len: 32 }) : null;
|
|
2058
|
+
}
|
|
2059
|
+
function readDiscordRateLimitScope(response) {
|
|
2060
|
+
const value = response.headers.get("X-RateLimit-Scope");
|
|
2061
|
+
return value && DISCORD_RATE_LIMIT_SCOPES.has(value) ? value : null;
|
|
2062
|
+
}
|
|
1949
2063
|
var DiscordError = class extends Error {
|
|
1950
2064
|
constructor(response, body) {
|
|
1951
|
-
|
|
2065
|
+
const redactedMessage = redactSensitiveFieldValue("message", readDiscordMessage(body, `Discord API request failed (${response.status})`));
|
|
2066
|
+
const redactedBody = redactDiscordErrorBody(body);
|
|
2067
|
+
super(redactedMessage);
|
|
1952
2068
|
this.name = "DiscordError";
|
|
1953
2069
|
this.status = response.status;
|
|
1954
2070
|
this.statusCode = response.status;
|
|
1955
|
-
this.rawBody =
|
|
1956
|
-
this.rawError =
|
|
2071
|
+
this.rawBody = redactedBody;
|
|
2072
|
+
this.rawError = redactedBody;
|
|
1957
2073
|
this.discordCode = readDiscordCode(body);
|
|
1958
2074
|
}
|
|
1959
2075
|
};
|
|
@@ -1962,21 +2078,30 @@ var RateLimitError = class extends DiscordError {
|
|
|
1962
2078
|
super(response, body);
|
|
1963
2079
|
this.name = "RateLimitError";
|
|
1964
2080
|
this.retryAfter = readRetryAfter(body, response, 1);
|
|
1965
|
-
this.scope = body.global ? "global" : response
|
|
1966
|
-
this.bucket = response
|
|
2081
|
+
this.scope = body.global ? "global" : readDiscordRateLimitScope(response);
|
|
2082
|
+
this.bucket = readDiscordRateLimitBucket(response);
|
|
1967
2083
|
}
|
|
1968
2084
|
};
|
|
1969
2085
|
//#endregion
|
|
1970
2086
|
//#region extensions/discord/src/internal/rest-routes.ts
|
|
1971
2087
|
const RATE_LIMIT_HEADER_NUMBER_RE = /^\d+(?:\.\d+)?$/;
|
|
2088
|
+
const DISCORD_ROUTE_IDENTIFIER_HASH_LENGTH = 32;
|
|
2089
|
+
function redactWebhookTokenInPath(path) {
|
|
2090
|
+
const hasLeadingSlash = path.startsWith("/");
|
|
2091
|
+
const segments = path.replace(/^\/+/, "").split("/");
|
|
2092
|
+
if (segments[0] !== "webhooks" || !segments[1] || !segments[2]) return path;
|
|
2093
|
+
segments[2] = redactIdentifier(segments[2], { len: DISCORD_ROUTE_IDENTIFIER_HASH_LENGTH });
|
|
2094
|
+
return `${hasLeadingSlash ? "/" : ""}${segments.join("/")}`;
|
|
2095
|
+
}
|
|
1972
2096
|
function createRouteKey(method, path) {
|
|
1973
|
-
|
|
2097
|
+
const pathname = path.split("?")[0] ?? path;
|
|
2098
|
+
return `${method.toUpperCase()} ${redactWebhookTokenInPath(pathname)}`;
|
|
1974
2099
|
}
|
|
1975
2100
|
function readTopLevelRouteKey(path) {
|
|
1976
2101
|
const [pathname = path] = path.split("?");
|
|
1977
2102
|
const [first, id, token] = pathname.replace(/^\/+/, "").split("/");
|
|
1978
2103
|
if (!first || !id) return pathname;
|
|
1979
|
-
if (first === "channels" || first === "guilds" || first === "webhooks") return first === "webhooks" && token ? `${first}/${id}/${token}` : `${first}/${id}`;
|
|
2104
|
+
if (first === "channels" || first === "guilds" || first === "webhooks") return first === "webhooks" && token ? `${first}/${id}/${redactIdentifier(token, { len: DISCORD_ROUTE_IDENTIFIER_HASH_LENGTH })}` : `${first}/${id}`;
|
|
1980
2105
|
return first;
|
|
1981
2106
|
}
|
|
1982
2107
|
function createBucketKey(bucket, path) {
|
|
@@ -2198,7 +2323,7 @@ var RestScheduler = class {
|
|
|
2198
2323
|
return target;
|
|
2199
2324
|
}
|
|
2200
2325
|
updateRateLimitState(routeKey, path, response, parsed) {
|
|
2201
|
-
const bucketHeader = response
|
|
2326
|
+
const bucketHeader = readDiscordRateLimitBucket(response);
|
|
2202
2327
|
const bucket = bucketHeader ? this.bindRouteToBucket(routeKey, createBucketKey(bucketHeader, path)) : this.getBucket(this.routeBuckets.get(routeKey) ?? routeKey);
|
|
2203
2328
|
bucket.bucket = bucketHeader ?? bucket.bucket;
|
|
2204
2329
|
const limit = readHeaderNumber(response.headers, "X-RateLimit-Limit");
|
|
@@ -2227,7 +2352,7 @@ var RestScheduler = class {
|
|
|
2227
2352
|
status: response.status
|
|
2228
2353
|
});
|
|
2229
2354
|
this.pruneInvalidRequests(now);
|
|
2230
|
-
const bucketHeader = response
|
|
2355
|
+
const bucketHeader = readDiscordRateLimitBucket(response);
|
|
2231
2356
|
const bucketKey = bucketHeader ? createBucketKey(bucketHeader, path) : this.routeBuckets.get(routeKey) ?? routeKey;
|
|
2232
2357
|
const bucket = this.buckets.get(bucketKey);
|
|
2233
2358
|
if (bucket) bucket.invalidRequests += 1;
|
|
@@ -2440,9 +2565,9 @@ var RequestClient = class {
|
|
|
2440
2565
|
this.options = normalizeRequestClientOptions(options);
|
|
2441
2566
|
this.scheduler = new RestScheduler({
|
|
2442
2567
|
lanes: normalizeSchedulerLanes(this.options.maxQueueSize, this.options.scheduler?.lanes),
|
|
2443
|
-
maxConcurrency:
|
|
2568
|
+
maxConcurrency: resolveIntegerOption(this.options.scheduler?.maxConcurrency, DEFAULT_MAX_CONCURRENT_WORKERS, { min: 1 }),
|
|
2444
2569
|
maxQueueSize: this.options.maxQueueSize,
|
|
2445
|
-
maxRateLimitRetries:
|
|
2570
|
+
maxRateLimitRetries: resolveIntegerOption(this.options.scheduler?.maxRateLimitRetries, 3, { min: 0 })
|
|
2446
2571
|
}, async (request) => await this.executeRequest(request.method, request.path, {
|
|
2447
2572
|
data: request.data,
|
|
2448
2573
|
query: request.query
|
|
@@ -2540,10 +2665,6 @@ var RequestClient = class {
|
|
|
2540
2665
|
this.requestControllers.clear();
|
|
2541
2666
|
}
|
|
2542
2667
|
};
|
|
2543
|
-
function normalizeIntegerOption(value, fallback, params) {
|
|
2544
|
-
const candidate = parseFiniteNumber(value) ?? fallback;
|
|
2545
|
-
return Math.max(params.min, Math.floor(candidate));
|
|
2546
|
-
}
|
|
2547
2668
|
function normalizeRequestClientOptions(options) {
|
|
2548
2669
|
const merged = {
|
|
2549
2670
|
...defaultOptions,
|
|
@@ -2551,13 +2672,13 @@ function normalizeRequestClientOptions(options) {
|
|
|
2551
2672
|
};
|
|
2552
2673
|
return {
|
|
2553
2674
|
...merged,
|
|
2554
|
-
apiVersion:
|
|
2675
|
+
apiVersion: resolveIntegerOption(merged.apiVersion, defaultOptions.apiVersion, { min: 1 }),
|
|
2555
2676
|
timeout: clampTimerTimeoutMs(merged.timeout, 1) ?? resolveTimerTimeoutMs(defaultOptions.timeout, 1),
|
|
2556
|
-
maxQueueSize:
|
|
2677
|
+
maxQueueSize: resolveIntegerOption(merged.maxQueueSize, defaultOptions.maxQueueSize, { min: 1 })
|
|
2557
2678
|
};
|
|
2558
2679
|
}
|
|
2559
2680
|
function normalizeSchedulerLanes(maxQueueSize, lanes) {
|
|
2560
|
-
const fallbackMaxQueueSize =
|
|
2681
|
+
const fallbackMaxQueueSize = resolveIntegerOption(maxQueueSize, defaultOptions.maxQueueSize, { min: 1 });
|
|
2561
2682
|
return {
|
|
2562
2683
|
critical: normalizeSchedulerLane("critical", fallbackMaxQueueSize, lanes?.critical),
|
|
2563
2684
|
standard: normalizeSchedulerLane("standard", fallbackMaxQueueSize, lanes?.standard),
|
|
@@ -2566,11 +2687,11 @@ function normalizeSchedulerLanes(maxQueueSize, lanes) {
|
|
|
2566
2687
|
}
|
|
2567
2688
|
function normalizeSchedulerLane(lane, maxQueueSize, options) {
|
|
2568
2689
|
const defaults = defaultLaneOptions[lane];
|
|
2569
|
-
const staleAfterMs = options?.staleAfterMs !== void 0 ?
|
|
2690
|
+
const staleAfterMs = options?.staleAfterMs !== void 0 ? resolveIntegerOption(options.staleAfterMs, defaults.staleAfterMs ?? 0, { min: 0 }) : defaults.staleAfterMs;
|
|
2570
2691
|
return {
|
|
2571
|
-
maxQueueSize: options?.maxQueueSize !== void 0 ?
|
|
2692
|
+
maxQueueSize: options?.maxQueueSize !== void 0 ? resolveIntegerOption(options.maxQueueSize, maxQueueSize, { min: 1 }) : maxQueueSize,
|
|
2572
2693
|
...staleAfterMs !== void 0 ? { staleAfterMs } : {},
|
|
2573
|
-
weight: options?.weight !== void 0 ?
|
|
2694
|
+
weight: options?.weight !== void 0 ? resolveIntegerOption(options.weight, defaults.weight, { min: 1 }) : defaults.weight
|
|
2574
2695
|
};
|
|
2575
2696
|
}
|
|
2576
2697
|
function getRequestPriority(method, path) {
|
|
@@ -2744,6 +2865,12 @@ var ThreadUpdateListener = class extends BaseListener {
|
|
|
2744
2865
|
this.type = GatewayDispatchEvents.ThreadUpdate;
|
|
2745
2866
|
}
|
|
2746
2867
|
};
|
|
2868
|
+
var ThreadDeleteListener = class extends BaseListener {
|
|
2869
|
+
constructor(..._args12) {
|
|
2870
|
+
super(..._args12);
|
|
2871
|
+
this.type = GatewayDispatchEvents.ThreadDelete;
|
|
2872
|
+
}
|
|
2873
|
+
};
|
|
2747
2874
|
//#endregion
|
|
2748
2875
|
//#region extensions/discord/src/internal/discord.ts
|
|
2749
2876
|
var discord_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -2797,6 +2924,7 @@ var discord_exports = /* @__PURE__ */ __exportAll({
|
|
|
2797
2924
|
StringSelectMenuInteraction: () => StringSelectMenuInteraction,
|
|
2798
2925
|
TextDisplay: () => TextDisplay,
|
|
2799
2926
|
TextInput: () => TextInput,
|
|
2927
|
+
ThreadDeleteListener: () => ThreadDeleteListener,
|
|
2800
2928
|
ThreadUpdateListener: () => ThreadUpdateListener,
|
|
2801
2929
|
Thumbnail: () => Thumbnail,
|
|
2802
2930
|
User: () => User,
|
|
@@ -2839,6 +2967,7 @@ var discord_exports = /* @__PURE__ */ __exportAll({
|
|
|
2839
2967
|
getThreadMember: () => getThreadMember,
|
|
2840
2968
|
getUser: () => getUser,
|
|
2841
2969
|
getWebhookMessage: () => getWebhookMessage,
|
|
2970
|
+
hasDiscordV2Components: () => hasDiscordV2Components,
|
|
2842
2971
|
isUnknownDiscordVoiceStateError: () => isUnknownDiscordVoiceStateError,
|
|
2843
2972
|
listApplicationCommands: () => listApplicationCommands,
|
|
2844
2973
|
listChannelArchivedThreads: () => listChannelArchivedThreads,
|
|
@@ -2869,55 +2998,6 @@ var discord_exports = /* @__PURE__ */ __exportAll({
|
|
|
2869
2998
|
import * as import_discord_api_types_v10 from "discord-api-types/v10";
|
|
2870
2999
|
__reExport(discord_exports, import_discord_api_types_v10);
|
|
2871
3000
|
//#endregion
|
|
2872
|
-
//#region extensions/discord/src/target-parsing.ts
|
|
2873
|
-
function parseDiscordTarget(raw, options = {}) {
|
|
2874
|
-
const trimmed = raw.trim();
|
|
2875
|
-
if (!trimmed) return;
|
|
2876
|
-
const providerPrefixedTarget = parseDiscordProviderPrefixedTarget(trimmed);
|
|
2877
|
-
if (providerPrefixedTarget) return providerPrefixedTarget;
|
|
2878
|
-
const userTarget = parseMentionPrefixOrAtUserTarget({
|
|
2879
|
-
raw: trimmed,
|
|
2880
|
-
mentionPattern: /^<@!?(\d+)>$/,
|
|
2881
|
-
prefixes: [
|
|
2882
|
-
{
|
|
2883
|
-
prefix: "user:",
|
|
2884
|
-
kind: "user"
|
|
2885
|
-
},
|
|
2886
|
-
{
|
|
2887
|
-
prefix: "channel:",
|
|
2888
|
-
kind: "channel"
|
|
2889
|
-
},
|
|
2890
|
-
{
|
|
2891
|
-
prefix: "discord:",
|
|
2892
|
-
kind: "user"
|
|
2893
|
-
}
|
|
2894
|
-
],
|
|
2895
|
-
atUserPattern: /^\d+$/,
|
|
2896
|
-
atUserErrorMessage: "Discord DMs require a user id (use user:<id> or a <@id> mention)"
|
|
2897
|
-
});
|
|
2898
|
-
if (userTarget) return userTarget;
|
|
2899
|
-
if (/^\d+$/.test(trimmed)) {
|
|
2900
|
-
if (options.defaultKind) return buildMessagingTarget(options.defaultKind, trimmed, trimmed);
|
|
2901
|
-
throw new Error(options.ambiguousMessage ?? `Ambiguous Discord recipient "${trimmed}". For DMs use "user:${trimmed}" or "<@${trimmed}>"; for channels use "channel:${trimmed}".`);
|
|
2902
|
-
}
|
|
2903
|
-
return buildMessagingTarget("channel", trimmed, trimmed);
|
|
2904
|
-
}
|
|
2905
|
-
function parseDiscordProviderPrefixedTarget(raw) {
|
|
2906
|
-
const match = /^discord:(channel|user):(.+)$/i.exec(raw);
|
|
2907
|
-
if (!match) return;
|
|
2908
|
-
const kind = match[1]?.toLowerCase();
|
|
2909
|
-
const id = match[2]?.trim();
|
|
2910
|
-
if (!kind || !id) return;
|
|
2911
|
-
return buildMessagingTarget(kind, id, `${kind}:${id}`);
|
|
2912
|
-
}
|
|
2913
|
-
function resolveDiscordChannelId(raw) {
|
|
2914
|
-
return requireTargetKind({
|
|
2915
|
-
platform: "Discord",
|
|
2916
|
-
target: parseDiscordTarget(raw, { defaultKind: "channel" }),
|
|
2917
|
-
kind: "channel"
|
|
2918
|
-
});
|
|
2919
|
-
}
|
|
2920
|
-
//#endregion
|
|
2921
3001
|
//#region extensions/discord/src/normalize.ts
|
|
2922
3002
|
function normalizeDiscordMessagingTarget(raw) {
|
|
2923
3003
|
return parseDiscordTarget(raw, { defaultKind: "channel" })?.normalized;
|
|
@@ -3224,4 +3304,101 @@ function rebalanceReasoningItalics(source, chunks, maxChars) {
|
|
|
3224
3304
|
return adjusted;
|
|
3225
3305
|
}
|
|
3226
3306
|
//#endregion
|
|
3227
|
-
|
|
3307
|
+
//#region extensions/discord/src/retry.ts
|
|
3308
|
+
const DISCORD_RETRY_DEFAULTS = {
|
|
3309
|
+
attempts: 3,
|
|
3310
|
+
minDelayMs: 500,
|
|
3311
|
+
maxDelayMs: 3e4,
|
|
3312
|
+
jitter: .1
|
|
3313
|
+
};
|
|
3314
|
+
const DISCORD_GATEWAY_RECONNECT_EXTRA_ATTEMPTS = 2;
|
|
3315
|
+
const DISCORD_TRANSIENT_MESSAGE_RE = /\b(?:bad gateway|fetch failed|network error|networkerror|service unavailable|socket hang up|temporarily unavailable|timed out|timeout)\b|connection (?:closed|reset|refused)/i;
|
|
3316
|
+
const ambiguousDiscordMessageCreates = /* @__PURE__ */ new WeakSet();
|
|
3317
|
+
function readDiscordErrorStatus(err) {
|
|
3318
|
+
if (!err || typeof err !== "object") return;
|
|
3319
|
+
return parseStrictNonNegativeInteger("status" in err && err.status !== void 0 ? err.status : "statusCode" in err && err.statusCode !== void 0 ? err.statusCode : void 0);
|
|
3320
|
+
}
|
|
3321
|
+
function classifyDiscordDeliveryFailure(error) {
|
|
3322
|
+
const candidates = collectErrorGraphCandidates(error, (current) => [current.cause, current.error]);
|
|
3323
|
+
for (const candidate of candidates) {
|
|
3324
|
+
const status = readDiscordErrorStatus(candidate);
|
|
3325
|
+
if (status !== void 0) {
|
|
3326
|
+
if (status === 408 || status >= 500) return "ambiguous";
|
|
3327
|
+
if (status >= 400) return "rejected";
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
if (candidates.some((candidate) => readErrorName(candidate) === "AbortError" || classifyTransientNetworkErrorCode(extractErrorCode(candidate)) === "ambiguous")) return "ambiguous";
|
|
3331
|
+
if (candidates.some((candidate) => classifyTransientNetworkErrorCode(extractErrorCode(candidate)) === "pre-connect")) return "pre-connect";
|
|
3332
|
+
return candidates.some((candidate) => (candidate instanceof Error || candidate !== null && typeof candidate === "object") && DISCORD_TRANSIENT_MESSAGE_RE.test(formatErrorMessage(candidate))) ? "ambiguous" : "unknown";
|
|
3333
|
+
}
|
|
3334
|
+
function recordDiscordMessageCreateAmbiguity(error) {
|
|
3335
|
+
if (error !== null && typeof error === "object") ambiguousDiscordMessageCreates.add(error);
|
|
3336
|
+
}
|
|
3337
|
+
function hasDiscordMessageCreateAmbiguity(error) {
|
|
3338
|
+
return collectErrorGraphCandidates(error, (current) => [current.cause, current.error]).some((candidate) => candidate !== null && typeof candidate === "object" && ambiguousDiscordMessageCreates.has(candidate));
|
|
3339
|
+
}
|
|
3340
|
+
function hasDiscordRateLimitRejection(error) {
|
|
3341
|
+
return error instanceof RateLimitError || collectErrorGraphCandidates(error, (current) => [current.cause, current.error]).some((candidate) => readDiscordErrorStatus(candidate) === 429);
|
|
3342
|
+
}
|
|
3343
|
+
function isRetryableDiscordTransientError(error) {
|
|
3344
|
+
const failure = classifyDiscordDeliveryFailure(error);
|
|
3345
|
+
return failure === "ambiguous" || failure === "pre-connect" || hasDiscordRateLimitRejection(error);
|
|
3346
|
+
}
|
|
3347
|
+
function isRetryableDiscordPreConnectError(error) {
|
|
3348
|
+
const failure = classifyDiscordDeliveryFailure(error);
|
|
3349
|
+
return failure === "pre-connect" || failure === "rejected" && hasDiscordRateLimitRejection(error);
|
|
3350
|
+
}
|
|
3351
|
+
function resolveDiscordRetryPredicate(safety) {
|
|
3352
|
+
return safety === "non-idempotent-create" ? isRetryableDiscordPreConnectError : isRetryableDiscordTransientError;
|
|
3353
|
+
}
|
|
3354
|
+
function isRetryableDiscordGatewayTransportError(err) {
|
|
3355
|
+
if (!isRetryableDiscordTransientError(err) || err instanceof RateLimitError) return false;
|
|
3356
|
+
return !collectErrorGraphCandidates(err, (current) => [current.cause, current.error]).some((candidate) => readDiscordErrorStatus(candidate) !== void 0);
|
|
3357
|
+
}
|
|
3358
|
+
function createDiscordRetryRunner(params) {
|
|
3359
|
+
const retryConfig = resolveRetryConfig(DISCORD_RETRY_DEFAULTS, params.retry);
|
|
3360
|
+
const attempts = retryConfig.attempts > 1 ? retryConfig.attempts + DISCORD_GATEWAY_RECONNECT_EXTRA_ATTEMPTS : retryConfig.attempts;
|
|
3361
|
+
return (fn, label, options) => {
|
|
3362
|
+
const isRetryable = resolveDiscordRetryPredicate(options?.safety ?? "idempotent");
|
|
3363
|
+
let observedGatewayDisconnect = false;
|
|
3364
|
+
const runRequest = async () => {
|
|
3365
|
+
if (params.signal?.aborted) throw params.signal.reason instanceof Error ? params.signal.reason : /* @__PURE__ */ new Error("Discord request aborted");
|
|
3366
|
+
observedGatewayDisconnect ||= params.isGatewayDisconnected?.() === true;
|
|
3367
|
+
try {
|
|
3368
|
+
return await fn();
|
|
3369
|
+
} catch (err) {
|
|
3370
|
+
observedGatewayDisconnect ||= params.isGatewayDisconnected?.() === true;
|
|
3371
|
+
throw err;
|
|
3372
|
+
}
|
|
3373
|
+
};
|
|
3374
|
+
const shouldRetry = (err, attempt) => isRetryable(err) && (attempt < retryConfig.attempts || observedGatewayDisconnect && isRetryableDiscordGatewayTransportError(err));
|
|
3375
|
+
const retryAfterMs = (err) => err instanceof RateLimitError ? err.retryAfter * 1e3 : void 0;
|
|
3376
|
+
const signal = params.signal;
|
|
3377
|
+
if (signal) return retryAsync(runRequest, {
|
|
3378
|
+
...retryConfig,
|
|
3379
|
+
attempts,
|
|
3380
|
+
label,
|
|
3381
|
+
shouldRetry,
|
|
3382
|
+
retryAfterMs,
|
|
3383
|
+
sleep: async (delayMs) => {
|
|
3384
|
+
try {
|
|
3385
|
+
await sleepWithAbort(delayMs, signal);
|
|
3386
|
+
} catch (error) {
|
|
3387
|
+
throw signal.aborted && signal.reason instanceof Error ? signal.reason : error;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
});
|
|
3391
|
+
return createChannelApiRetryRunner({
|
|
3392
|
+
retry: {
|
|
3393
|
+
...retryConfig,
|
|
3394
|
+
attempts
|
|
3395
|
+
},
|
|
3396
|
+
shouldRetry,
|
|
3397
|
+
strictShouldRetry: true,
|
|
3398
|
+
retryAfterMs,
|
|
3399
|
+
verbose: params.verbose
|
|
3400
|
+
})(runRequest, label);
|
|
3401
|
+
};
|
|
3402
|
+
}
|
|
3403
|
+
//#endregion
|
|
3404
|
+
export { MediaGallery as $, timeoutGuildMember as $t, RateLimitError as A, pinChannelMessage as At, hasDiscordV2Components as B, deleteChannelPermission as Bt, ThreadDeleteListener as C, editChannelMessage as Ct, Plugin as D, listChannelArchivedThreads as Dt, Client as E, getThreadMember as Et, Command as F, createGuildBan as Ft, Modal as G, listGuildChannels as Gt, Embed as H, getGuildMember as Ht, CommandWithSubcommands as I, createGuildChannel as It, Button as J, listGuildScheduledEvents as Jt, RadioGroup as K, listGuildEmojis as Kt, Guild as L, createGuildEmoji as Lt, readDiscordCode as M, sendChannelTyping as Mt, readDiscordMessage as N, unpinChannelMessage as Nt, RequestClient as O, listChannelMessages as Ot, readRetryAfter as P, addGuildMemberRole as Pt, LinkButton as Q, removeGuildMemberRole as Qt, Message as R, createGuildScheduledEvent as Rt, ResumedListener as S, editChannel as St, VoiceStateUpdateListener as T, getChannelMessage as Tt, CheckboxGroup as U, getGuildVoiceState as Ut, serializePayload as V, getGuild as Vt, Label as W, listGuildActiveThreads as Wt, Container as X, putChannelPermission as Xt, ChannelSelectMenu as Y, moveGuildChannels as Yt, File as Z, removeGuildMember as Zt, MessageCreateListener as _, listMessageReactionUsers as _t, chunkDiscordTextWithMode as a, StringSelectMenu as at, PresenceUpdateListener as b, deleteChannel as bt, resolveDiscordReplyReference as c, UserSelectMenu as ct, normalizeDiscordMessagingTarget as d, stripUndefinedFields as dt, __exportAll as en, MentionableSelectMenu as et, normalizeDiscordOutboundTarget as f, createChannelWebhook as ft, InteractionCreateListener as g, deleteOwnMessageReaction as gt, GuildDeleteListener as h, createOwnMessageReaction as ht, recordDiscordMessageCreateAmbiguity as i, Separator as it, isUnknownDiscordVoiceStateError as j, searchGuildMessages as jt, DiscordError as k, listChannelPins as kt, allowFromContainsDiscordUserId as l, BaseMessageInteractiveComponent as lt, GuildCreateListener as m, getCurrentUser as mt, createDiscordRetryRunner as n, Row as nt, createReusableDiscordReplyReference as o, TextDisplay as ot, discord_exports as p, createUserDmChannel as pt, TextInput as q, listGuildRoles as qt, hasDiscordMessageCreateAmbiguity as r, Section as rt, resolveDiscordReplyMessageId as s, Thumbnail as st, classifyDiscordDeliveryFailure as t, RoleSelectMenu as tt, looksLikeDiscordTargetId as u, parseCustomId as ut, MessageReactionAddListener as v, createChannelMessage as vt, ThreadUpdateListener as w, getChannel as wt, ReadyListener as x, deleteChannelMessage as xt, MessageReactionRemoveListener as y, createThread as yt, User as z, createGuildSticker as zt };
|