shardwire 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -44
- package/dist/index.d.mts +133 -7
- package/dist/index.d.ts +133 -7
- package/dist/index.js +508 -92
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +509 -92
- package/dist/index.mjs.map +1 -1
- package/package.json +82 -75
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ var BOT_EVENT_NAMES = [
|
|
|
6
6
|
"messageCreate",
|
|
7
7
|
"messageUpdate",
|
|
8
8
|
"messageDelete",
|
|
9
|
+
"messageBulkDelete",
|
|
9
10
|
"messageReactionAdd",
|
|
10
11
|
"messageReactionRemove",
|
|
11
12
|
"guildCreate",
|
|
@@ -15,7 +16,10 @@ var BOT_EVENT_NAMES = [
|
|
|
15
16
|
"guildMemberUpdate",
|
|
16
17
|
"threadCreate",
|
|
17
18
|
"threadUpdate",
|
|
18
|
-
"threadDelete"
|
|
19
|
+
"threadDelete",
|
|
20
|
+
"channelCreate",
|
|
21
|
+
"channelUpdate",
|
|
22
|
+
"channelDelete"
|
|
19
23
|
];
|
|
20
24
|
var BOT_ACTION_NAMES = [
|
|
21
25
|
"sendMessage",
|
|
@@ -36,7 +40,14 @@ var BOT_ACTION_NAMES = [
|
|
|
36
40
|
"addMemberRole",
|
|
37
41
|
"removeMemberRole",
|
|
38
42
|
"addMessageReaction",
|
|
39
|
-
"removeOwnMessageReaction"
|
|
43
|
+
"removeOwnMessageReaction",
|
|
44
|
+
"timeoutMember",
|
|
45
|
+
"removeMemberTimeout",
|
|
46
|
+
"createChannel",
|
|
47
|
+
"editChannel",
|
|
48
|
+
"deleteChannel",
|
|
49
|
+
"createThread",
|
|
50
|
+
"archiveThread"
|
|
40
51
|
];
|
|
41
52
|
var DISCORD_GATEWAY_INTENT_ENTRIES = Object.entries(GatewayIntentBits).filter(
|
|
42
53
|
(entry) => typeof entry[1] === "number"
|
|
@@ -50,6 +61,7 @@ var EVENT_REQUIRED_INTENTS = {
|
|
|
50
61
|
messageCreate: ["GuildMessages"],
|
|
51
62
|
messageUpdate: ["GuildMessages"],
|
|
52
63
|
messageDelete: ["GuildMessages"],
|
|
64
|
+
messageBulkDelete: ["GuildMessages"],
|
|
53
65
|
messageReactionAdd: ["GuildMessageReactions"],
|
|
54
66
|
messageReactionRemove: ["GuildMessageReactions"],
|
|
55
67
|
guildCreate: ["Guilds"],
|
|
@@ -59,11 +71,16 @@ var EVENT_REQUIRED_INTENTS = {
|
|
|
59
71
|
guildMemberUpdate: ["GuildMembers"],
|
|
60
72
|
threadCreate: ["Guilds"],
|
|
61
73
|
threadUpdate: ["Guilds"],
|
|
62
|
-
threadDelete: ["Guilds"]
|
|
74
|
+
threadDelete: ["Guilds"],
|
|
75
|
+
channelCreate: ["Guilds"],
|
|
76
|
+
channelUpdate: ["Guilds"],
|
|
77
|
+
channelDelete: ["Guilds"]
|
|
63
78
|
};
|
|
64
79
|
function getAvailableEvents(intents) {
|
|
65
80
|
const enabled = new Set(intents);
|
|
66
|
-
return BOT_EVENT_NAMES.filter(
|
|
81
|
+
return BOT_EVENT_NAMES.filter(
|
|
82
|
+
(eventName) => EVENT_REQUIRED_INTENTS[eventName].every((intent) => enabled.has(intent))
|
|
83
|
+
);
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
// src/discord/runtime/adapter.ts
|
|
@@ -80,6 +97,7 @@ var ActionExecutionError = class extends Error {
|
|
|
80
97
|
|
|
81
98
|
// src/discord/runtime/discordjs-adapter.ts
|
|
82
99
|
import {
|
|
100
|
+
ChannelType,
|
|
83
101
|
Client,
|
|
84
102
|
DiscordAPIError,
|
|
85
103
|
Events,
|
|
@@ -155,6 +173,20 @@ function serializeMessage(message) {
|
|
|
155
173
|
...message.reference.guildId ? { guildId: message.reference.guildId } : {}
|
|
156
174
|
} : void 0;
|
|
157
175
|
const components = "components" in message && message.components && message.components.length > 0 ? message.components.map((row) => row.toJSON()) : void 0;
|
|
176
|
+
const channelMeta = (() => {
|
|
177
|
+
if (!("channel" in message) || !message.channel) {
|
|
178
|
+
return {};
|
|
179
|
+
}
|
|
180
|
+
const ch = message.channel;
|
|
181
|
+
const meta = {};
|
|
182
|
+
if (typeof ch.type === "number") {
|
|
183
|
+
meta.channelType = ch.type;
|
|
184
|
+
}
|
|
185
|
+
if ("parentId" in ch && typeof ch.parentId === "string") {
|
|
186
|
+
meta.parentChannelId = ch.parentId;
|
|
187
|
+
}
|
|
188
|
+
return meta;
|
|
189
|
+
})();
|
|
158
190
|
return {
|
|
159
191
|
id: message.id,
|
|
160
192
|
channelId: message.channelId,
|
|
@@ -173,7 +205,8 @@ function serializeMessage(message) {
|
|
|
173
205
|
})) : [],
|
|
174
206
|
embeds: serializeEmbeds(message),
|
|
175
207
|
...components ? { components } : {},
|
|
176
|
-
...reference ? { reference } : {}
|
|
208
|
+
...reference ? { reference } : {},
|
|
209
|
+
...channelMeta
|
|
177
210
|
};
|
|
178
211
|
}
|
|
179
212
|
function serializeGuild(guild) {
|
|
@@ -195,12 +228,43 @@ function serializeThread(thread) {
|
|
|
195
228
|
...typeof thread.locked === "boolean" ? { locked: thread.locked } : {}
|
|
196
229
|
};
|
|
197
230
|
}
|
|
231
|
+
function serializeChannel(channel) {
|
|
232
|
+
const base = {
|
|
233
|
+
id: channel.id,
|
|
234
|
+
type: channel.type
|
|
235
|
+
};
|
|
236
|
+
if ("name" in channel) {
|
|
237
|
+
base.name = channel.name ?? null;
|
|
238
|
+
}
|
|
239
|
+
if ("guildId" in channel && typeof channel.guildId === "string") {
|
|
240
|
+
base.guildId = channel.guildId;
|
|
241
|
+
}
|
|
242
|
+
if ("parentId" in channel) {
|
|
243
|
+
base.parentId = channel.parentId;
|
|
244
|
+
}
|
|
245
|
+
return base;
|
|
246
|
+
}
|
|
198
247
|
function serializeDeletedMessage(message) {
|
|
248
|
+
const channelMeta = (() => {
|
|
249
|
+
if (!("channel" in message) || !message.channel) {
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
const ch = message.channel;
|
|
253
|
+
const meta = {};
|
|
254
|
+
if (typeof ch.type === "number") {
|
|
255
|
+
meta.channelType = ch.type;
|
|
256
|
+
}
|
|
257
|
+
if ("parentId" in ch && typeof ch.parentId === "string") {
|
|
258
|
+
meta.parentChannelId = ch.parentId;
|
|
259
|
+
}
|
|
260
|
+
return meta;
|
|
261
|
+
})();
|
|
199
262
|
return {
|
|
200
263
|
id: message.id,
|
|
201
264
|
channelId: message.channelId,
|
|
202
265
|
...message.guildId ? { guildId: message.guildId } : {},
|
|
203
|
-
deletedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
266
|
+
deletedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
267
|
+
...channelMeta
|
|
204
268
|
};
|
|
205
269
|
}
|
|
206
270
|
function serializeReactionEmoji(reaction) {
|
|
@@ -266,83 +330,124 @@ function serializeInteraction(interaction) {
|
|
|
266
330
|
...interaction.member && "guild" in interaction.member ? { member: serializeGuildMember(interaction.member) } : {}
|
|
267
331
|
};
|
|
268
332
|
if (interaction.isChatInputCommand()) {
|
|
269
|
-
return
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
333
|
+
return enrichInteractionChannel(
|
|
334
|
+
{
|
|
335
|
+
...base,
|
|
336
|
+
kind: "chatInput",
|
|
337
|
+
commandName: interaction.commandName,
|
|
338
|
+
options: serializeChatInputOptions(interaction)
|
|
339
|
+
},
|
|
340
|
+
interaction
|
|
341
|
+
);
|
|
275
342
|
}
|
|
276
343
|
if (interaction.isContextMenuCommand()) {
|
|
277
|
-
return
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
344
|
+
return enrichInteractionChannel(
|
|
345
|
+
{
|
|
346
|
+
...base,
|
|
347
|
+
kind: "contextMenu",
|
|
348
|
+
commandName: interaction.commandName
|
|
349
|
+
},
|
|
350
|
+
interaction
|
|
351
|
+
);
|
|
282
352
|
}
|
|
283
353
|
if (interaction.isButton()) {
|
|
284
354
|
const message = serializeInteractionMessage(interaction);
|
|
285
|
-
return
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
355
|
+
return enrichInteractionChannel(
|
|
356
|
+
{
|
|
357
|
+
...base,
|
|
358
|
+
kind: "button",
|
|
359
|
+
customId: interaction.customId,
|
|
360
|
+
...message ? { message } : {}
|
|
361
|
+
},
|
|
362
|
+
interaction
|
|
363
|
+
);
|
|
291
364
|
}
|
|
292
365
|
if (interaction.isStringSelectMenu()) {
|
|
293
366
|
const message = serializeInteractionMessage(interaction);
|
|
294
|
-
return
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
367
|
+
return enrichInteractionChannel(
|
|
368
|
+
{
|
|
369
|
+
...base,
|
|
370
|
+
kind: "stringSelect",
|
|
371
|
+
...serializeSelectMenu(interaction),
|
|
372
|
+
...message ? { message } : {}
|
|
373
|
+
},
|
|
374
|
+
interaction
|
|
375
|
+
);
|
|
300
376
|
}
|
|
301
377
|
if (interaction.isUserSelectMenu()) {
|
|
302
378
|
const message = serializeInteractionMessage(interaction);
|
|
303
|
-
return
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
379
|
+
return enrichInteractionChannel(
|
|
380
|
+
{
|
|
381
|
+
...base,
|
|
382
|
+
kind: "userSelect",
|
|
383
|
+
...serializeSelectMenu(interaction),
|
|
384
|
+
...message ? { message } : {}
|
|
385
|
+
},
|
|
386
|
+
interaction
|
|
387
|
+
);
|
|
309
388
|
}
|
|
310
389
|
if (interaction.isRoleSelectMenu()) {
|
|
311
390
|
const message = serializeInteractionMessage(interaction);
|
|
312
|
-
return
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
391
|
+
return enrichInteractionChannel(
|
|
392
|
+
{
|
|
393
|
+
...base,
|
|
394
|
+
kind: "roleSelect",
|
|
395
|
+
...serializeSelectMenu(interaction),
|
|
396
|
+
...message ? { message } : {}
|
|
397
|
+
},
|
|
398
|
+
interaction
|
|
399
|
+
);
|
|
318
400
|
}
|
|
319
401
|
if (interaction.isMentionableSelectMenu()) {
|
|
320
402
|
const message = serializeInteractionMessage(interaction);
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
403
|
+
return enrichInteractionChannel(
|
|
404
|
+
{
|
|
405
|
+
...base,
|
|
406
|
+
kind: "mentionableSelect",
|
|
407
|
+
...serializeSelectMenu(interaction),
|
|
408
|
+
...message ? { message } : {}
|
|
409
|
+
},
|
|
410
|
+
interaction
|
|
411
|
+
);
|
|
327
412
|
}
|
|
328
413
|
if (interaction.isChannelSelectMenu()) {
|
|
329
414
|
const message = serializeInteractionMessage(interaction);
|
|
330
|
-
return
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
415
|
+
return enrichInteractionChannel(
|
|
416
|
+
{
|
|
417
|
+
...base,
|
|
418
|
+
kind: "channelSelect",
|
|
419
|
+
...serializeSelectMenu(interaction),
|
|
420
|
+
...message ? { message } : {}
|
|
421
|
+
},
|
|
422
|
+
interaction
|
|
423
|
+
);
|
|
336
424
|
}
|
|
337
425
|
if (interaction.isModalSubmit()) {
|
|
338
|
-
return
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
426
|
+
return enrichInteractionChannel(
|
|
427
|
+
{
|
|
428
|
+
...base,
|
|
429
|
+
kind: "modalSubmit",
|
|
430
|
+
customId: interaction.customId,
|
|
431
|
+
fields: serializeModalFields(interaction)
|
|
432
|
+
},
|
|
433
|
+
interaction
|
|
434
|
+
);
|
|
344
435
|
}
|
|
345
|
-
return base;
|
|
436
|
+
return enrichInteractionChannel(base, interaction);
|
|
437
|
+
}
|
|
438
|
+
function enrichInteractionChannel(base, interaction) {
|
|
439
|
+
if (!("channel" in interaction) || !interaction.channel || interaction.channel.isDMBased()) {
|
|
440
|
+
return base;
|
|
441
|
+
}
|
|
442
|
+
const ch = interaction.channel;
|
|
443
|
+
const out = { ...base };
|
|
444
|
+
if (typeof ch.type === "number") {
|
|
445
|
+
out.channelType = ch.type;
|
|
446
|
+
}
|
|
447
|
+
if ("parentId" in ch && typeof ch.parentId === "string") {
|
|
448
|
+
out.parentChannelId = ch.parentId;
|
|
449
|
+
}
|
|
450
|
+
return out;
|
|
346
451
|
}
|
|
347
452
|
|
|
348
453
|
// src/discord/runtime/discordjs-adapter.ts
|
|
@@ -405,15 +510,24 @@ function mapDiscordErrorToActionExecutionError(error) {
|
|
|
405
510
|
return new ActionExecutionError("INVALID_REQUEST", message, detailPayload);
|
|
406
511
|
}
|
|
407
512
|
if (details.status === 429) {
|
|
513
|
+
let retryAfterMs;
|
|
514
|
+
if (error instanceof DiscordAPIError) {
|
|
515
|
+
const raw = error.rawError;
|
|
516
|
+
const retryAfter = raw?.retry_after;
|
|
517
|
+
if (typeof retryAfter === "number" && Number.isFinite(retryAfter)) {
|
|
518
|
+
retryAfterMs = Math.max(0, Math.ceil(retryAfter * 1e3));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
408
521
|
return new ActionExecutionError("SERVICE_UNAVAILABLE", message, {
|
|
409
522
|
discordStatus: 429,
|
|
410
523
|
retryable: true,
|
|
411
|
-
...details.code !== void 0 ? { discordCode: details.code } : {}
|
|
524
|
+
...details.code !== void 0 ? { discordCode: details.code } : {},
|
|
525
|
+
...retryAfterMs !== void 0 ? { retryAfterMs } : {}
|
|
412
526
|
});
|
|
413
527
|
}
|
|
414
528
|
return null;
|
|
415
529
|
}
|
|
416
|
-
var DiscordJsRuntimeAdapter = class {
|
|
530
|
+
var DiscordJsRuntimeAdapter = class _DiscordJsRuntimeAdapter {
|
|
417
531
|
constructor(options) {
|
|
418
532
|
this.options = options;
|
|
419
533
|
const intentBits = options.intents.map((intent) => BOT_INTENT_BITS[intent]);
|
|
@@ -443,7 +557,14 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
443
557
|
addMemberRole: (payload) => this.addMemberRole(payload),
|
|
444
558
|
removeMemberRole: (payload) => this.removeMemberRole(payload),
|
|
445
559
|
addMessageReaction: (payload) => this.addMessageReaction(payload),
|
|
446
|
-
removeOwnMessageReaction: (payload) => this.removeOwnMessageReaction(payload)
|
|
560
|
+
removeOwnMessageReaction: (payload) => this.removeOwnMessageReaction(payload),
|
|
561
|
+
timeoutMember: (payload) => this.timeoutMember(payload),
|
|
562
|
+
removeMemberTimeout: (payload) => this.removeMemberTimeout(payload),
|
|
563
|
+
createChannel: (payload) => this.createChannel(payload),
|
|
564
|
+
editChannel: (payload) => this.editChannel(payload),
|
|
565
|
+
deleteChannel: (payload) => this.deleteChannel(payload),
|
|
566
|
+
createThread: (payload) => this.createThread(payload),
|
|
567
|
+
archiveThread: (payload) => this.archiveThread(payload)
|
|
447
568
|
};
|
|
448
569
|
}
|
|
449
570
|
options;
|
|
@@ -571,6 +692,23 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
571
692
|
this.client.off(Events.MessageDelete, listener);
|
|
572
693
|
};
|
|
573
694
|
}
|
|
695
|
+
case "messageBulkDelete": {
|
|
696
|
+
const listener = (messages, channel) => {
|
|
697
|
+
handler({
|
|
698
|
+
receivedAt: Date.now(),
|
|
699
|
+
...this.shardEnvelope(),
|
|
700
|
+
channelId: channel.id,
|
|
701
|
+
guildId: channel.guildId,
|
|
702
|
+
messageIds: [...messages.keys()],
|
|
703
|
+
channelType: channel.type,
|
|
704
|
+
..."parentId" in channel && typeof channel.parentId === "string" ? { parentChannelId: channel.parentId } : {}
|
|
705
|
+
});
|
|
706
|
+
};
|
|
707
|
+
this.client.on(Events.MessageBulkDelete, listener);
|
|
708
|
+
return () => {
|
|
709
|
+
this.client.off(Events.MessageBulkDelete, listener);
|
|
710
|
+
};
|
|
711
|
+
}
|
|
574
712
|
case "messageReactionAdd": {
|
|
575
713
|
const listener = (reaction, user) => {
|
|
576
714
|
handler({
|
|
@@ -708,6 +846,46 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
708
846
|
this.client.off(Events.ThreadDelete, listener);
|
|
709
847
|
};
|
|
710
848
|
}
|
|
849
|
+
case "channelCreate": {
|
|
850
|
+
const listener = (channel) => {
|
|
851
|
+
handler({
|
|
852
|
+
receivedAt: Date.now(),
|
|
853
|
+
...this.shardEnvelope(),
|
|
854
|
+
channel: serializeChannel(channel)
|
|
855
|
+
});
|
|
856
|
+
};
|
|
857
|
+
this.client.on(Events.ChannelCreate, listener);
|
|
858
|
+
return () => {
|
|
859
|
+
this.client.off(Events.ChannelCreate, listener);
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
case "channelUpdate": {
|
|
863
|
+
const listener = (oldChannel, newChannel) => {
|
|
864
|
+
handler({
|
|
865
|
+
receivedAt: Date.now(),
|
|
866
|
+
...this.shardEnvelope(),
|
|
867
|
+
oldChannel: serializeChannel(oldChannel),
|
|
868
|
+
channel: serializeChannel(newChannel)
|
|
869
|
+
});
|
|
870
|
+
};
|
|
871
|
+
this.client.on(Events.ChannelUpdate, listener);
|
|
872
|
+
return () => {
|
|
873
|
+
this.client.off(Events.ChannelUpdate, listener);
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
case "channelDelete": {
|
|
877
|
+
const listener = (channel) => {
|
|
878
|
+
handler({
|
|
879
|
+
receivedAt: Date.now(),
|
|
880
|
+
...this.shardEnvelope(),
|
|
881
|
+
channel: serializeChannel(channel)
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
this.client.on(Events.ChannelDelete, listener);
|
|
885
|
+
return () => {
|
|
886
|
+
this.client.off(Events.ChannelDelete, listener);
|
|
887
|
+
};
|
|
888
|
+
}
|
|
711
889
|
default:
|
|
712
890
|
return () => void 0;
|
|
713
891
|
}
|
|
@@ -726,7 +904,10 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
726
904
|
throw mappedError;
|
|
727
905
|
}
|
|
728
906
|
this.logger.error("Discord action execution failed.", { action: name, error: String(error) });
|
|
729
|
-
throw new ActionExecutionError(
|
|
907
|
+
throw new ActionExecutionError(
|
|
908
|
+
"INTERNAL_ERROR",
|
|
909
|
+
error instanceof Error ? error.message : "Discord action failed."
|
|
910
|
+
);
|
|
730
911
|
}
|
|
731
912
|
}
|
|
732
913
|
async fetchSendableChannel(channelId) {
|
|
@@ -794,7 +975,10 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
794
975
|
async replyToInteraction(payload) {
|
|
795
976
|
const interaction = this.getReplyCapableInteraction(payload.interactionId);
|
|
796
977
|
if (interaction.replied || interaction.deferred) {
|
|
797
|
-
throw new ActionExecutionError(
|
|
978
|
+
throw new ActionExecutionError(
|
|
979
|
+
"INVALID_REQUEST",
|
|
980
|
+
`Interaction "${payload.interactionId}" has already been acknowledged.`
|
|
981
|
+
);
|
|
798
982
|
}
|
|
799
983
|
const reply = await interaction.reply({
|
|
800
984
|
...toSendOptions(payload),
|
|
@@ -806,7 +990,10 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
806
990
|
async deferInteraction(payload) {
|
|
807
991
|
const interaction = this.getReplyCapableInteraction(payload.interactionId);
|
|
808
992
|
if (interaction.replied) {
|
|
809
|
-
throw new ActionExecutionError(
|
|
993
|
+
throw new ActionExecutionError(
|
|
994
|
+
"INVALID_REQUEST",
|
|
995
|
+
`Interaction "${payload.interactionId}" has already been replied to.`
|
|
996
|
+
);
|
|
810
997
|
}
|
|
811
998
|
if (!interaction.deferred) {
|
|
812
999
|
await interaction.deferReply({
|
|
@@ -829,7 +1016,10 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
829
1016
|
async followUpInteraction(payload) {
|
|
830
1017
|
const interaction = this.getReplyCapableInteraction(payload.interactionId);
|
|
831
1018
|
if (!interaction.replied && !interaction.deferred) {
|
|
832
|
-
throw new ActionExecutionError(
|
|
1019
|
+
throw new ActionExecutionError(
|
|
1020
|
+
"INVALID_REQUEST",
|
|
1021
|
+
`Interaction "${payload.interactionId}" has not been acknowledged yet.`
|
|
1022
|
+
);
|
|
833
1023
|
}
|
|
834
1024
|
const followUp = await interaction.followUp({
|
|
835
1025
|
...toSendOptions(payload),
|
|
@@ -938,7 +1128,10 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
938
1128
|
return candidate.emoji.identifier === payload.emoji || candidate.emoji.name === payload.emoji || candidate.emoji.toString() === payload.emoji;
|
|
939
1129
|
});
|
|
940
1130
|
if (!reaction) {
|
|
941
|
-
throw new ActionExecutionError(
|
|
1131
|
+
throw new ActionExecutionError(
|
|
1132
|
+
"NOT_FOUND",
|
|
1133
|
+
`Reaction "${payload.emoji}" was not found on message "${payload.messageId}".`
|
|
1134
|
+
);
|
|
942
1135
|
}
|
|
943
1136
|
await reaction.users.remove(ownUserId);
|
|
944
1137
|
return {
|
|
@@ -947,6 +1140,112 @@ var DiscordJsRuntimeAdapter = class {
|
|
|
947
1140
|
emoji: payload.emoji
|
|
948
1141
|
};
|
|
949
1142
|
}
|
|
1143
|
+
static maxTimeoutMs = 28 * 24 * 60 * 60 * 1e3;
|
|
1144
|
+
async timeoutMember(payload) {
|
|
1145
|
+
if (typeof payload.durationMs !== "number" || !Number.isFinite(payload.durationMs) || payload.durationMs < 1 || payload.durationMs > _DiscordJsRuntimeAdapter.maxTimeoutMs) {
|
|
1146
|
+
throw new ActionExecutionError(
|
|
1147
|
+
"INVALID_REQUEST",
|
|
1148
|
+
`durationMs must be between 1 and ${_DiscordJsRuntimeAdapter.maxTimeoutMs} (28 days).`
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
const guild = await this.client.guilds.fetch(payload.guildId);
|
|
1152
|
+
const member = await guild.members.fetch(payload.userId);
|
|
1153
|
+
await member.timeout(payload.durationMs, payload.reason);
|
|
1154
|
+
return {
|
|
1155
|
+
guildId: payload.guildId,
|
|
1156
|
+
userId: payload.userId
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
async removeMemberTimeout(payload) {
|
|
1160
|
+
const guild = await this.client.guilds.fetch(payload.guildId);
|
|
1161
|
+
const member = await guild.members.fetch(payload.userId);
|
|
1162
|
+
await member.timeout(null, payload.reason);
|
|
1163
|
+
return serializeGuildMember(await member.fetch());
|
|
1164
|
+
}
|
|
1165
|
+
async createChannel(payload) {
|
|
1166
|
+
const guild = await this.client.guilds.fetch(payload.guildId);
|
|
1167
|
+
const created = await guild.channels.create({
|
|
1168
|
+
name: payload.name,
|
|
1169
|
+
type: payload.type ?? ChannelType.GuildText,
|
|
1170
|
+
...payload.parentId ? { parent: payload.parentId } : {},
|
|
1171
|
+
...payload.topic !== void 0 ? { topic: payload.topic } : {},
|
|
1172
|
+
...payload.reason ? { reason: payload.reason } : {}
|
|
1173
|
+
});
|
|
1174
|
+
return serializeChannel(created);
|
|
1175
|
+
}
|
|
1176
|
+
async editChannel(payload) {
|
|
1177
|
+
const raw = await this.client.channels.fetch(payload.channelId);
|
|
1178
|
+
if (!raw) {
|
|
1179
|
+
throw new ActionExecutionError("NOT_FOUND", `Channel "${payload.channelId}" was not found.`);
|
|
1180
|
+
}
|
|
1181
|
+
if (!("edit" in raw) || typeof raw.edit !== "function") {
|
|
1182
|
+
throw new ActionExecutionError("INVALID_REQUEST", `Channel "${payload.channelId}" cannot be edited.`);
|
|
1183
|
+
}
|
|
1184
|
+
const edited = await raw.edit({
|
|
1185
|
+
...payload.name !== void 0 ? { name: payload.name ?? void 0 } : {},
|
|
1186
|
+
...payload.parentId !== void 0 ? { parent: payload.parentId } : {},
|
|
1187
|
+
...payload.topic !== void 0 ? { topic: payload.topic } : {},
|
|
1188
|
+
...payload.reason ? { reason: payload.reason } : {}
|
|
1189
|
+
});
|
|
1190
|
+
return serializeChannel(edited);
|
|
1191
|
+
}
|
|
1192
|
+
async deleteChannel(payload) {
|
|
1193
|
+
const raw = await this.client.channels.fetch(payload.channelId);
|
|
1194
|
+
if (!raw) {
|
|
1195
|
+
throw new ActionExecutionError("NOT_FOUND", `Channel "${payload.channelId}" was not found.`);
|
|
1196
|
+
}
|
|
1197
|
+
if (!("delete" in raw) || typeof raw.delete !== "function") {
|
|
1198
|
+
throw new ActionExecutionError("INVALID_REQUEST", `Channel "${payload.channelId}" cannot be deleted.`);
|
|
1199
|
+
}
|
|
1200
|
+
await raw.delete(payload.reason);
|
|
1201
|
+
return {
|
|
1202
|
+
deleted: true,
|
|
1203
|
+
channelId: payload.channelId
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
async createThread(payload) {
|
|
1207
|
+
const parent = await this.client.channels.fetch(payload.parentChannelId);
|
|
1208
|
+
if (!parent || !parent.isTextBased()) {
|
|
1209
|
+
throw new ActionExecutionError(
|
|
1210
|
+
"NOT_FOUND",
|
|
1211
|
+
`Parent channel "${payload.parentChannelId}" was not found or is not text-based.`
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
if (payload.messageId) {
|
|
1215
|
+
if (!("messages" in parent) || !parent.messages) {
|
|
1216
|
+
throw new ActionExecutionError(
|
|
1217
|
+
"INVALID_REQUEST",
|
|
1218
|
+
`Channel "${payload.parentChannelId}" does not support fetching messages.`
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
const msg = await parent.messages.fetch(payload.messageId);
|
|
1222
|
+
const thread2 = await msg.startThread({
|
|
1223
|
+
name: payload.name,
|
|
1224
|
+
...payload.reason ? { reason: payload.reason } : {},
|
|
1225
|
+
...payload.autoArchiveDuration ? { autoArchiveDuration: payload.autoArchiveDuration } : {}
|
|
1226
|
+
});
|
|
1227
|
+
return serializeThread(thread2);
|
|
1228
|
+
}
|
|
1229
|
+
if (!("threads" in parent) || !parent.threads || typeof parent.threads.create !== "function") {
|
|
1230
|
+
throw new ActionExecutionError("INVALID_REQUEST", `Channel "${payload.parentChannelId}" cannot create threads.`);
|
|
1231
|
+
}
|
|
1232
|
+
const threadOptions = Object.assign(
|
|
1233
|
+
{ name: payload.name },
|
|
1234
|
+
payload.type === "private" ? { type: ChannelType.PrivateThread } : {},
|
|
1235
|
+
payload.reason ? { reason: payload.reason } : {},
|
|
1236
|
+
payload.autoArchiveDuration ? { autoArchiveDuration: payload.autoArchiveDuration } : {}
|
|
1237
|
+
);
|
|
1238
|
+
const thread = await parent.threads.create(threadOptions);
|
|
1239
|
+
return serializeThread(thread);
|
|
1240
|
+
}
|
|
1241
|
+
async archiveThread(payload) {
|
|
1242
|
+
const raw = await this.client.channels.fetch(payload.threadId);
|
|
1243
|
+
if (!raw || !raw.isThread()) {
|
|
1244
|
+
throw new ActionExecutionError("NOT_FOUND", `Thread "${payload.threadId}" was not found.`);
|
|
1245
|
+
}
|
|
1246
|
+
await raw.setArchived(payload.archived ?? true, payload.reason);
|
|
1247
|
+
return serializeThread(raw);
|
|
1248
|
+
}
|
|
950
1249
|
};
|
|
951
1250
|
function createDiscordJsRuntimeAdapter(options) {
|
|
952
1251
|
return new DiscordJsRuntimeAdapter(options);
|
|
@@ -968,6 +1267,7 @@ function createConnectionId() {
|
|
|
968
1267
|
}
|
|
969
1268
|
|
|
970
1269
|
// src/bridge/subscriptions.ts
|
|
1270
|
+
var THREAD_CHANNEL_TYPES = /* @__PURE__ */ new Set([10, 11, 12]);
|
|
971
1271
|
function normalizeStringList(value) {
|
|
972
1272
|
if (value === void 0) {
|
|
973
1273
|
return void 0;
|
|
@@ -976,12 +1276,24 @@ function normalizeStringList(value) {
|
|
|
976
1276
|
const normalized = [...new Set(rawValues.filter((entry) => typeof entry === "string" && entry.length > 0))].sort();
|
|
977
1277
|
return normalized.length > 0 ? normalized : void 0;
|
|
978
1278
|
}
|
|
1279
|
+
function normalizeNumberList(value) {
|
|
1280
|
+
if (value === void 0) {
|
|
1281
|
+
return void 0;
|
|
1282
|
+
}
|
|
1283
|
+
const rawValues = Array.isArray(value) ? value : [value];
|
|
1284
|
+
const normalized = [
|
|
1285
|
+
...new Set(rawValues.filter((entry) => typeof entry === "number" && Number.isFinite(entry)))
|
|
1286
|
+
].sort((a, b) => a - b);
|
|
1287
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
1288
|
+
}
|
|
979
1289
|
function normalizeKindList(value) {
|
|
980
1290
|
if (value === void 0) {
|
|
981
1291
|
return void 0;
|
|
982
1292
|
}
|
|
983
1293
|
const rawValues = Array.isArray(value) ? value : [value];
|
|
984
|
-
const normalized = [
|
|
1294
|
+
const normalized = [
|
|
1295
|
+
...new Set(rawValues.filter((entry) => typeof entry === "string"))
|
|
1296
|
+
].sort();
|
|
985
1297
|
return normalized.length > 0 ? normalized : void 0;
|
|
986
1298
|
}
|
|
987
1299
|
function normalizeEventSubscriptionFilter(filter) {
|
|
@@ -995,6 +1307,9 @@ function normalizeEventSubscriptionFilter(filter) {
|
|
|
995
1307
|
const commandNames = normalizeStringList(filter.commandName);
|
|
996
1308
|
const customIds = normalizeStringList(filter.customId);
|
|
997
1309
|
const interactionKinds = normalizeKindList(filter.interactionKind);
|
|
1310
|
+
const channelTypes = normalizeNumberList(filter.channelType);
|
|
1311
|
+
const parentChannelIds = normalizeStringList(filter.parentChannelId);
|
|
1312
|
+
const threadIds = normalizeStringList(filter.threadId);
|
|
998
1313
|
if (guildIds) {
|
|
999
1314
|
normalized.guildId = guildIds;
|
|
1000
1315
|
}
|
|
@@ -1013,6 +1328,15 @@ function normalizeEventSubscriptionFilter(filter) {
|
|
|
1013
1328
|
if (interactionKinds) {
|
|
1014
1329
|
normalized.interactionKind = interactionKinds;
|
|
1015
1330
|
}
|
|
1331
|
+
if (channelTypes) {
|
|
1332
|
+
normalized.channelType = channelTypes;
|
|
1333
|
+
}
|
|
1334
|
+
if (parentChannelIds) {
|
|
1335
|
+
normalized.parentChannelId = parentChannelIds;
|
|
1336
|
+
}
|
|
1337
|
+
if (threadIds) {
|
|
1338
|
+
normalized.threadId = threadIds;
|
|
1339
|
+
}
|
|
1016
1340
|
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
1017
1341
|
}
|
|
1018
1342
|
function normalizeEventSubscription(subscription) {
|
|
@@ -1043,6 +1367,24 @@ function matchesKind(value, allowed) {
|
|
|
1043
1367
|
}
|
|
1044
1368
|
return allowed.includes(value);
|
|
1045
1369
|
}
|
|
1370
|
+
function matchesNumberField(value, allowed) {
|
|
1371
|
+
if (!allowed) {
|
|
1372
|
+
return true;
|
|
1373
|
+
}
|
|
1374
|
+
if (value === void 0) {
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
return allowed.includes(value);
|
|
1378
|
+
}
|
|
1379
|
+
function threadIdFromMessageLike(message) {
|
|
1380
|
+
if (message.channelType === void 0) {
|
|
1381
|
+
return void 0;
|
|
1382
|
+
}
|
|
1383
|
+
if (THREAD_CHANNEL_TYPES.has(message.channelType)) {
|
|
1384
|
+
return message.channelId;
|
|
1385
|
+
}
|
|
1386
|
+
return void 0;
|
|
1387
|
+
}
|
|
1046
1388
|
function eventMetadata(name, payload) {
|
|
1047
1389
|
switch (name) {
|
|
1048
1390
|
case "ready":
|
|
@@ -1050,36 +1392,66 @@ function eventMetadata(name, payload) {
|
|
|
1050
1392
|
case "interactionCreate": {
|
|
1051
1393
|
const interactionPayload = payload;
|
|
1052
1394
|
const ix = interactionPayload.interaction;
|
|
1395
|
+
const threadId = ix.channelId && ix.channelType !== void 0 && THREAD_CHANNEL_TYPES.has(ix.channelType) ? ix.channelId : void 0;
|
|
1053
1396
|
return {
|
|
1054
1397
|
...ix.guildId ? { guildId: ix.guildId } : {},
|
|
1055
1398
|
...ix.channelId ? { channelId: ix.channelId } : {},
|
|
1056
1399
|
userId: ix.user.id,
|
|
1057
1400
|
...ix.commandName ? { commandName: ix.commandName } : {},
|
|
1058
1401
|
...ix.customId ? { customId: ix.customId } : {},
|
|
1059
|
-
interactionKind: ix.kind
|
|
1402
|
+
interactionKind: ix.kind,
|
|
1403
|
+
...ix.channelType !== void 0 ? { channelType: ix.channelType } : {},
|
|
1404
|
+
...ix.parentChannelId ? { parentChannelId: ix.parentChannelId } : {},
|
|
1405
|
+
...threadId ? { threadId } : {}
|
|
1060
1406
|
};
|
|
1061
1407
|
}
|
|
1062
1408
|
case "messageCreate": {
|
|
1063
1409
|
const messagePayload = payload;
|
|
1410
|
+
const msg = messagePayload.message;
|
|
1411
|
+
const threadId = threadIdFromMessageLike(msg);
|
|
1064
1412
|
return {
|
|
1065
|
-
...
|
|
1066
|
-
channelId:
|
|
1067
|
-
...
|
|
1413
|
+
...msg.guildId ? { guildId: msg.guildId } : {},
|
|
1414
|
+
channelId: msg.channelId,
|
|
1415
|
+
...msg.author ? { userId: msg.author.id } : {},
|
|
1416
|
+
...msg.channelType !== void 0 ? { channelType: msg.channelType } : {},
|
|
1417
|
+
...msg.parentChannelId ? { parentChannelId: msg.parentChannelId } : {},
|
|
1418
|
+
...threadId ? { threadId } : {}
|
|
1068
1419
|
};
|
|
1069
1420
|
}
|
|
1070
1421
|
case "messageUpdate": {
|
|
1071
1422
|
const messagePayload = payload;
|
|
1423
|
+
const msg = messagePayload.message;
|
|
1424
|
+
const threadId = threadIdFromMessageLike(msg);
|
|
1072
1425
|
return {
|
|
1073
|
-
...
|
|
1074
|
-
channelId:
|
|
1075
|
-
...
|
|
1426
|
+
...msg.guildId ? { guildId: msg.guildId } : {},
|
|
1427
|
+
channelId: msg.channelId,
|
|
1428
|
+
...msg.author ? { userId: msg.author.id } : {},
|
|
1429
|
+
...msg.channelType !== void 0 ? { channelType: msg.channelType } : {},
|
|
1430
|
+
...msg.parentChannelId ? { parentChannelId: msg.parentChannelId } : {},
|
|
1431
|
+
...threadId ? { threadId } : {}
|
|
1076
1432
|
};
|
|
1077
1433
|
}
|
|
1078
1434
|
case "messageDelete": {
|
|
1079
1435
|
const messagePayload = payload;
|
|
1436
|
+
const msg = messagePayload.message;
|
|
1437
|
+
const threadId = threadIdFromMessageLike(msg);
|
|
1080
1438
|
return {
|
|
1081
|
-
...
|
|
1082
|
-
channelId:
|
|
1439
|
+
...msg.guildId ? { guildId: msg.guildId } : {},
|
|
1440
|
+
channelId: msg.channelId,
|
|
1441
|
+
...msg.channelType !== void 0 ? { channelType: msg.channelType } : {},
|
|
1442
|
+
...msg.parentChannelId ? { parentChannelId: msg.parentChannelId } : {},
|
|
1443
|
+
...threadId ? { threadId } : {}
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
case "messageBulkDelete": {
|
|
1447
|
+
const bulkPayload = payload;
|
|
1448
|
+
const threadId = bulkPayload.channelType !== void 0 && THREAD_CHANNEL_TYPES.has(bulkPayload.channelType) ? bulkPayload.channelId : void 0;
|
|
1449
|
+
return {
|
|
1450
|
+
guildId: bulkPayload.guildId,
|
|
1451
|
+
channelId: bulkPayload.channelId,
|
|
1452
|
+
...bulkPayload.channelType !== void 0 ? { channelType: bulkPayload.channelType } : {},
|
|
1453
|
+
...bulkPayload.parentChannelId ? { parentChannelId: bulkPayload.parentChannelId } : {},
|
|
1454
|
+
...threadId ? { threadId } : {}
|
|
1083
1455
|
};
|
|
1084
1456
|
}
|
|
1085
1457
|
case "messageReactionAdd": {
|
|
@@ -1132,7 +1504,22 @@ function eventMetadata(name, payload) {
|
|
|
1132
1504
|
const threadPayload = payload;
|
|
1133
1505
|
return {
|
|
1134
1506
|
guildId: threadPayload.thread.guildId,
|
|
1135
|
-
...threadPayload.thread.parentId ? { channelId: threadPayload.thread.parentId } : { channelId: threadPayload.thread.id }
|
|
1507
|
+
...threadPayload.thread.parentId ? { channelId: threadPayload.thread.parentId } : { channelId: threadPayload.thread.id },
|
|
1508
|
+
channelType: threadPayload.thread.type,
|
|
1509
|
+
...threadPayload.thread.parentId ? { parentChannelId: threadPayload.thread.parentId } : {},
|
|
1510
|
+
threadId: threadPayload.thread.id
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
case "channelCreate":
|
|
1514
|
+
case "channelUpdate":
|
|
1515
|
+
case "channelDelete": {
|
|
1516
|
+
const channelPayload = payload;
|
|
1517
|
+
const ch = channelPayload.channel;
|
|
1518
|
+
return {
|
|
1519
|
+
...ch.guildId ? { guildId: ch.guildId } : {},
|
|
1520
|
+
channelId: ch.id,
|
|
1521
|
+
channelType: ch.type,
|
|
1522
|
+
...ch.parentId ? { parentChannelId: ch.parentId } : {}
|
|
1136
1523
|
};
|
|
1137
1524
|
}
|
|
1138
1525
|
default:
|
|
@@ -1145,7 +1532,7 @@ function matchesEventSubscription(subscription, payload) {
|
|
|
1145
1532
|
return true;
|
|
1146
1533
|
}
|
|
1147
1534
|
const metadata = eventMetadata(normalized.name, payload);
|
|
1148
|
-
return matchesField(metadata.guildId, normalized.filter.guildId) && matchesField(metadata.channelId, normalized.filter.channelId) && matchesField(metadata.userId, normalized.filter.userId) && matchesField(metadata.commandName, normalized.filter.commandName) && matchesField(metadata.customId, normalized.filter.customId) && matchesKind(metadata.interactionKind, normalized.filter.interactionKind);
|
|
1535
|
+
return matchesField(metadata.guildId, normalized.filter.guildId) && matchesField(metadata.channelId, normalized.filter.channelId) && matchesField(metadata.userId, normalized.filter.userId) && matchesField(metadata.commandName, normalized.filter.commandName) && matchesField(metadata.customId, normalized.filter.customId) && matchesKind(metadata.interactionKind, normalized.filter.interactionKind) && matchesNumberField(metadata.channelType, normalized.filter.channelType) && matchesField(metadata.parentChannelId, normalized.filter.parentChannelId) && matchesField(metadata.threadId, normalized.filter.threadId);
|
|
1149
1536
|
}
|
|
1150
1537
|
|
|
1151
1538
|
// src/bridge/transport/security.ts
|
|
@@ -1247,6 +1634,8 @@ var BridgeTransportServer = class {
|
|
|
1247
1634
|
const maxConcurrent = config.options.server.maxConcurrentActions ?? 32;
|
|
1248
1635
|
const queueTimeout = config.options.server.actionQueueTimeoutMs ?? 5e3;
|
|
1249
1636
|
this.actionSemaphore = new AsyncSemaphore(maxConcurrent, queueTimeout);
|
|
1637
|
+
this.idempotencyTtlMs = config.options.server.idempotencyTtlMs ?? 12e4;
|
|
1638
|
+
this.idempotencyScope = config.options.server.idempotencyScope ?? "connection";
|
|
1250
1639
|
this.wss = new WebSocketServer({
|
|
1251
1640
|
host: config.options.server.host,
|
|
1252
1641
|
port: config.options.server.port,
|
|
@@ -1269,7 +1658,8 @@ var BridgeTransportServer = class {
|
|
|
1269
1658
|
stickyEvents = /* @__PURE__ */ new Map();
|
|
1270
1659
|
actionSemaphore;
|
|
1271
1660
|
idempotencyCache = /* @__PURE__ */ new Map();
|
|
1272
|
-
idempotencyTtlMs
|
|
1661
|
+
idempotencyTtlMs;
|
|
1662
|
+
idempotencyScope;
|
|
1273
1663
|
authBuckets = /* @__PURE__ */ new Map();
|
|
1274
1664
|
connectionCount() {
|
|
1275
1665
|
let count = 0;
|
|
@@ -1499,7 +1889,7 @@ var BridgeTransportServer = class {
|
|
|
1499
1889
|
}
|
|
1500
1890
|
const idempotencyRaw = payload.idempotencyKey;
|
|
1501
1891
|
const idempotencyKey = typeof idempotencyRaw === "string" && idempotencyRaw.length > 0 && idempotencyRaw.length <= 256 ? idempotencyRaw : void 0;
|
|
1502
|
-
const idempotencyCacheKey = idempotencyKey ?
|
|
1892
|
+
const idempotencyCacheKey = idempotencyKey ? this.idempotencyScope === "secret" && activeSecret ? `secret:${activeSecret.id}:${idempotencyKey}` : `conn:${state.id}:${idempotencyKey}` : void 0;
|
|
1503
1893
|
if (idempotencyCacheKey) {
|
|
1504
1894
|
this.pruneIdempotencyCache(Date.now());
|
|
1505
1895
|
const cached = this.idempotencyCache.get(idempotencyCacheKey);
|
|
@@ -1512,9 +1902,7 @@ var BridgeTransportServer = class {
|
|
|
1512
1902
|
});
|
|
1513
1903
|
this.safeSend(
|
|
1514
1904
|
state.socket,
|
|
1515
|
-
stringifyEnvelope(
|
|
1516
|
-
makeEnvelope(replay.ok ? "action.result" : "action.error", replay, { requestId })
|
|
1517
|
-
)
|
|
1905
|
+
stringifyEnvelope(makeEnvelope(replay.ok ? "action.result" : "action.error", replay, { requestId }))
|
|
1518
1906
|
);
|
|
1519
1907
|
return;
|
|
1520
1908
|
}
|
|
@@ -1705,11 +2093,7 @@ function normalizeSecretEntry(secret, index) {
|
|
|
1705
2093
|
value: scoped.value,
|
|
1706
2094
|
scope: {
|
|
1707
2095
|
events: normalizeScopeList(scoped.allow?.events, BOT_EVENT_NAMES, `server.secrets[${index}].allow.events`),
|
|
1708
|
-
actions: normalizeScopeList(
|
|
1709
|
-
scoped.allow?.actions,
|
|
1710
|
-
BOT_ACTION_NAMES,
|
|
1711
|
-
`server.secrets[${index}].allow.actions`
|
|
1712
|
-
)
|
|
2096
|
+
actions: normalizeScopeList(scoped.allow?.actions, BOT_ACTION_NAMES, `server.secrets[${index}].allow.actions`)
|
|
1713
2097
|
}
|
|
1714
2098
|
};
|
|
1715
2099
|
}
|
|
@@ -1736,6 +2120,14 @@ function assertBotBridgeOptions(options) {
|
|
|
1736
2120
|
if (options.server.actionQueueTimeoutMs !== void 0) {
|
|
1737
2121
|
assertPositiveNumber("server.actionQueueTimeoutMs", options.server.actionQueueTimeoutMs);
|
|
1738
2122
|
}
|
|
2123
|
+
if (options.server.idempotencyScope !== void 0) {
|
|
2124
|
+
if (options.server.idempotencyScope !== "connection" && options.server.idempotencyScope !== "secret") {
|
|
2125
|
+
throw new Error('server.idempotencyScope must be "connection" or "secret".');
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
if (options.server.idempotencyTtlMs !== void 0) {
|
|
2129
|
+
assertPositiveNumber("server.idempotencyTtlMs", options.server.idempotencyTtlMs);
|
|
2130
|
+
}
|
|
1739
2131
|
if (!Array.isArray(options.server.secrets) || options.server.secrets.length === 0) {
|
|
1740
2132
|
throw new Error("server.secrets must contain at least one secret.");
|
|
1741
2133
|
}
|
|
@@ -1935,6 +2327,24 @@ var AppRequestError = class extends Error {
|
|
|
1935
2327
|
code;
|
|
1936
2328
|
};
|
|
1937
2329
|
var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
|
|
2330
|
+
function metricsExtrasFromActionError(error) {
|
|
2331
|
+
const details = error.details;
|
|
2332
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
|
2333
|
+
return {};
|
|
2334
|
+
}
|
|
2335
|
+
const obj = details;
|
|
2336
|
+
const extras = {};
|
|
2337
|
+
if (typeof obj.retryAfterMs === "number" && Number.isFinite(obj.retryAfterMs)) {
|
|
2338
|
+
extras.retryAfterMs = obj.retryAfterMs;
|
|
2339
|
+
}
|
|
2340
|
+
if (typeof obj.discordStatus === "number" && Number.isFinite(obj.discordStatus)) {
|
|
2341
|
+
extras.discordStatus = obj.discordStatus;
|
|
2342
|
+
}
|
|
2343
|
+
if (typeof obj.discordCode === "number" && Number.isFinite(obj.discordCode)) {
|
|
2344
|
+
extras.discordCode = obj.discordCode;
|
|
2345
|
+
}
|
|
2346
|
+
return extras;
|
|
2347
|
+
}
|
|
1938
2348
|
function connectBotBridge(options) {
|
|
1939
2349
|
assertAppBridgeOptions(options);
|
|
1940
2350
|
const logger = withLogger(options.logger);
|
|
@@ -2243,7 +2653,7 @@ function connectBotBridge(options) {
|
|
|
2243
2653
|
requestId,
|
|
2244
2654
|
durationMs: Date.now() - started,
|
|
2245
2655
|
ok: result.ok,
|
|
2246
|
-
...!result.ok ? { errorCode: result.error.code } : {}
|
|
2656
|
+
...!result.ok ? { errorCode: result.error.code, ...metricsExtrasFromActionError(result.error) } : {}
|
|
2247
2657
|
});
|
|
2248
2658
|
return result;
|
|
2249
2659
|
} catch (error) {
|
|
@@ -2285,7 +2695,14 @@ function connectBotBridge(options) {
|
|
|
2285
2695
|
addMemberRole: (payload, sendOptions) => invokeAction("addMemberRole", payload, sendOptions),
|
|
2286
2696
|
removeMemberRole: (payload, sendOptions) => invokeAction("removeMemberRole", payload, sendOptions),
|
|
2287
2697
|
addMessageReaction: (payload, sendOptions) => invokeAction("addMessageReaction", payload, sendOptions),
|
|
2288
|
-
removeOwnMessageReaction: (payload, sendOptions) => invokeAction("removeOwnMessageReaction", payload, sendOptions)
|
|
2698
|
+
removeOwnMessageReaction: (payload, sendOptions) => invokeAction("removeOwnMessageReaction", payload, sendOptions),
|
|
2699
|
+
timeoutMember: (payload, sendOptions) => invokeAction("timeoutMember", payload, sendOptions),
|
|
2700
|
+
removeMemberTimeout: (payload, sendOptions) => invokeAction("removeMemberTimeout", payload, sendOptions),
|
|
2701
|
+
createChannel: (payload, sendOptions) => invokeAction("createChannel", payload, sendOptions),
|
|
2702
|
+
editChannel: (payload, sendOptions) => invokeAction("editChannel", payload, sendOptions),
|
|
2703
|
+
deleteChannel: (payload, sendOptions) => invokeAction("deleteChannel", payload, sendOptions),
|
|
2704
|
+
createThread: (payload, sendOptions) => invokeAction("createThread", payload, sendOptions),
|
|
2705
|
+
archiveThread: (payload, sendOptions) => invokeAction("archiveThread", payload, sendOptions)
|
|
2289
2706
|
};
|
|
2290
2707
|
return {
|
|
2291
2708
|
actions,
|