@seedcord/gateway 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +136 -44
- package/dist/index.mjs +207 -136
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -14
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { WinstonConsoleSink, WinstonFileSink, installNodeDefaults } from "@seedcord/logger/node";
|
|
3
|
-
import { EventMetadataKey, GateNotice, GatedMetadataKey, HmrManager, InteractionMetadataKey,
|
|
3
|
+
import { EventMetadataKey, GateNotice, GatedMetadataKey, HmrManager, InteractionMetadataKey, MiddlewareMetadataKey, MissingPermissions, NoticeCard, PermissionNames, PublishDefault, accessorStore, areRoutes, asError, busLoggerOf, clearStore, decodeComponentRoute, deferFlags, guardedAccessor, interactionRoutesOf, isEmojiTuple, outcomeFor, pickNotice, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runHandlerGates, sendFlags, setBotColor, slowGateMonitor } from "@seedcord/core/internal";
|
|
4
4
|
import { SeedcordErrorCode, paint } from "@seedcord/errors";
|
|
5
5
|
import { SeedcordError, SeedcordTypeError, validateDiscordToken } from "@seedcord/errors/internal";
|
|
6
|
-
import { ArraySourceBase, BaseHandler as BaseHandler$1, BaseReplySender, BuilderComponent, Bus, CursorSourceBase, CustomId, DispatchContext, Fault, Notice, PaginatorBase, RepliableHandler as RepliableHandler$1, ResolvedEmoji, RowComponent, Silence, Subscriber as Subscriber$1, WebhookLog as WebhookLog$1, assertPermissions, defineGate } from "@seedcord/core";
|
|
6
|
+
import { ArraySourceBase, BaseHandler as BaseHandler$1, BaseReplySender, BuilderComponent, Bus, CursorSourceBase, CustomId, DispatchContext, Fault, InteractionKind, Notice, PaginatorBase, RepliableHandler as RepliableHandler$1, ResolvedEmoji, RowComponent, Silence, Subscriber as Subscriber$1, WebhookLog as WebhookLog$1, assertPermissions, defineGate } from "@seedcord/core";
|
|
7
7
|
import { Logger, LoggerChannelRegistry } from "@seedcord/logger";
|
|
8
8
|
import { ButtonStyle, Client, ComponentType, DiscordAPIError, Events, GatewayIntentBits, Guild, GuildMember, IntentsBitField, InteractionContextType, Message, MessageFlags, PermissionFlagsBits, RESTJSONErrorCodes, Role, User } from "discord.js";
|
|
9
9
|
import { ButtonBuilder, TextDisplayBuilder } from "@discordjs/builders";
|
|
10
10
|
import { buildSlashRoute } from "@seedcord/utils/internal";
|
|
11
11
|
import { Plugin as Plugin$1 } from "@seedcord/core/plugin";
|
|
12
12
|
import { CoordinatedShutdown, CoordinatedStartup, Pluggable } from "@seedcord/core/node";
|
|
13
|
-
import { CommandRegistry, HealthCheck, ShutdownPhase, StartupPhase, SubscriberLoader,
|
|
13
|
+
import { CommandRegistry, DRAIN_TASK_TIMEOUT_MS, DRAIN_WINDOW_MS, HealthCheck, ShutdownPhase, StartupPhase, SubscriberLoader, drainInFlight, shutdownOf } from "@seedcord/core/node/internal";
|
|
14
14
|
import { MemoryRateLimiter } from "@seedcord/rate-limiter";
|
|
15
15
|
import { HostAugmentTarget, HostVersion, SeedcordBrand } from "@seedcord/types/internal";
|
|
16
16
|
import { Envapter } from "envapt";
|
|
@@ -655,8 +655,8 @@ var ReplySender = class extends BaseReplySender {
|
|
|
655
655
|
* Shared base the repliable interaction handlers extend.
|
|
656
656
|
*
|
|
657
657
|
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
658
|
-
* {@link
|
|
659
|
-
* to the gateway sender.
|
|
658
|
+
* {@link ContextMenuHandler}, or one of the select menu bases instead. This class binds the core
|
|
659
|
+
* reply base to the gateway sender.
|
|
660
660
|
*
|
|
661
661
|
* @typeParam Event - The repliable interaction type this handler processes
|
|
662
662
|
*/
|
|
@@ -676,8 +676,8 @@ var RepliableHandler = class extends RepliableHandler$1 {
|
|
|
676
676
|
* Shared base the typed interaction handlers extend.
|
|
677
677
|
*
|
|
678
678
|
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
679
|
-
* or
|
|
680
|
-
* share.
|
|
679
|
+
* or one of the select menu bases instead. This class adds `showModal` on top of the reply members
|
|
680
|
+
* those bases share.
|
|
681
681
|
*
|
|
682
682
|
* @typeParam Repliable - The interaction type this handler processes
|
|
683
683
|
*/
|
|
@@ -997,8 +997,8 @@ var AutocompleteHandler = class extends BaseHandler {
|
|
|
997
997
|
/**
|
|
998
998
|
* Shared base the customId-routed component handlers extend.
|
|
999
999
|
*
|
|
1000
|
-
* Not a public entry point. Extend {@link ButtonHandler}, {@link
|
|
1001
|
-
* instead. This class defines the customId decode and the route matching those bases share.
|
|
1000
|
+
* Not a public entry point. Extend {@link ButtonHandler}, {@link ModalHandler}, or one of the select menu
|
|
1001
|
+
* bases instead. This class defines the customId decode and the route matching those bases share.
|
|
1002
1002
|
*
|
|
1003
1003
|
* @typeParam Event - The component interaction type this handler processes
|
|
1004
1004
|
* @typeParam Defs - The customId route definitions registered on the concrete handler
|
|
@@ -1137,23 +1137,56 @@ var ModalHandler = class extends ComponentHandler {
|
|
|
1137
1137
|
//#endregion
|
|
1138
1138
|
//#region src/handlers/interaction/components/SelectMenuHandler.ts
|
|
1139
1139
|
/**
|
|
1140
|
-
*
|
|
1140
|
+
* Shared base the select menu handlers extend.
|
|
1141
1141
|
*
|
|
1142
|
-
*
|
|
1143
|
-
*
|
|
1144
|
-
*
|
|
1142
|
+
* Not a public entry point. Extend {@link StringMenuHandler}, {@link UserMenuHandler},
|
|
1143
|
+
* {@link RoleMenuHandler}, {@link ChannelMenuHandler}, or {@link MentionableMenuHandler} instead. This
|
|
1144
|
+
* class defines the `values` getter those bases share.
|
|
1145
1145
|
*
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
1146
|
+
* @typeParam Event - The select menu interaction type this handler processes
|
|
1147
|
+
* @typeParam Defs - The customId route definitions registered on the concrete handler
|
|
1148
|
+
*/
|
|
1149
|
+
var SelectMenuHandler = class extends ComponentHandler {
|
|
1150
|
+
/** The values this select picked. On every kind but the string menu they are snowflake ids. */
|
|
1151
|
+
get values() {
|
|
1152
|
+
return this.event.values;
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
/**
|
|
1156
|
+
* Base class for a string select menu handler.
|
|
1157
|
+
*
|
|
1158
|
+
* Register the customId definitions with `@StringMenuRoute`, list the same ones in the generic, then read
|
|
1159
|
+
* the chosen option values from `this.values`. Read `this.params` for a single route or `this.match` for
|
|
1160
|
+
* several. Reply through the handler members, or rewrite the source message with `this.update`.
|
|
1161
|
+
*
|
|
1162
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof TopicsId]`.
|
|
1163
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1164
|
+
*
|
|
1165
|
+
* @example
|
|
1166
|
+
* ```ts
|
|
1167
|
+
* \@StringMenuRoute(TopicsId)
|
|
1168
|
+
* class Topics extends StringMenuHandler<[typeof TopicsId]> {
|
|
1169
|
+
* async execute() {
|
|
1170
|
+
* const { userId } = this.params;
|
|
1171
|
+
* await this.update(`<@${userId}> now follows ${this.values.join(', ')}`);
|
|
1172
|
+
* }
|
|
1173
|
+
* }
|
|
1174
|
+
* ```
|
|
1175
|
+
*/
|
|
1176
|
+
var StringMenuHandler = class extends SelectMenuHandler {};
|
|
1177
|
+
/**
|
|
1178
|
+
* Base class for a user select menu handler.
|
|
1179
|
+
*
|
|
1180
|
+
* Beside `this.values` this handler declares `this.users` and `this.members`. Register the customId
|
|
1181
|
+
* definitions with `@UserMenuRoute` and list the same ones in the generic.
|
|
1148
1182
|
*
|
|
1149
|
-
* @typeParam Kind - The select kind from {@link SelectMenuKind}, e.g. `SelectMenuKind.User`.
|
|
1150
1183
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
|
|
1151
1184
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1152
1185
|
*
|
|
1153
1186
|
* @example
|
|
1154
1187
|
* ```ts
|
|
1155
|
-
* \@
|
|
1156
|
-
* class
|
|
1188
|
+
* \@UserMenuRoute(AssignId)
|
|
1189
|
+
* class Assign extends UserMenuHandler<[typeof AssignId]> {
|
|
1157
1190
|
* async execute() {
|
|
1158
1191
|
* const { roleId } = this.params;
|
|
1159
1192
|
* await this.reply(`assigning ${this.users.size} member(s) to <@&${roleId}>`);
|
|
@@ -1161,29 +1194,97 @@ var ModalHandler = class extends ComponentHandler {
|
|
|
1161
1194
|
* }
|
|
1162
1195
|
* ```
|
|
1163
1196
|
*/
|
|
1164
|
-
var
|
|
1165
|
-
eventMember(key) {
|
|
1166
|
-
return this.event[key];
|
|
1167
|
-
}
|
|
1168
|
-
/** The ids this select picked. */
|
|
1169
|
-
get values() {
|
|
1170
|
-
return this.eventMember("values");
|
|
1171
|
-
}
|
|
1197
|
+
var UserMenuHandler = class extends SelectMenuHandler {
|
|
1172
1198
|
/** The users this select picked. */
|
|
1173
1199
|
get users() {
|
|
1174
|
-
return this.
|
|
1200
|
+
return this.event.users;
|
|
1175
1201
|
}
|
|
1176
1202
|
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1177
1203
|
get members() {
|
|
1178
|
-
return this.
|
|
1204
|
+
return this.event.members;
|
|
1179
1205
|
}
|
|
1206
|
+
};
|
|
1207
|
+
/**
|
|
1208
|
+
* Base class for a role select menu handler.
|
|
1209
|
+
*
|
|
1210
|
+
* Beside `this.values` this handler declares `this.roles`. Register the customId definitions with
|
|
1211
|
+
* `@RoleMenuRoute` and list the same ones in the generic.
|
|
1212
|
+
*
|
|
1213
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof GrantId]`.
|
|
1214
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1215
|
+
*
|
|
1216
|
+
* @example
|
|
1217
|
+
* ```ts
|
|
1218
|
+
* \@RoleMenuRoute(GrantId)
|
|
1219
|
+
* class Grant extends RoleMenuHandler<[typeof GrantId]> {
|
|
1220
|
+
* async execute() {
|
|
1221
|
+
* await this.update(`granting ${this.roles.size} role(s)`);
|
|
1222
|
+
* }
|
|
1223
|
+
* }
|
|
1224
|
+
* ```
|
|
1225
|
+
*/
|
|
1226
|
+
var RoleMenuHandler = class extends SelectMenuHandler {
|
|
1180
1227
|
/** The roles this select picked. */
|
|
1181
1228
|
get roles() {
|
|
1182
|
-
return this.
|
|
1229
|
+
return this.event.roles;
|
|
1183
1230
|
}
|
|
1231
|
+
};
|
|
1232
|
+
/**
|
|
1233
|
+
* Base class for a channel select menu handler.
|
|
1234
|
+
*
|
|
1235
|
+
* Beside `this.values` this handler declares `this.channels`. Register the customId definitions with
|
|
1236
|
+
* `@ChannelMenuRoute` and list the same ones in the generic.
|
|
1237
|
+
*
|
|
1238
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof LogTargetId]`.
|
|
1239
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
* ```ts
|
|
1243
|
+
* \@ChannelMenuRoute(LogTargetId)
|
|
1244
|
+
* class LogTarget extends ChannelMenuHandler<[typeof LogTargetId]> {
|
|
1245
|
+
* async execute() {
|
|
1246
|
+
* await this.update(`logging to ${this.channels.size} channel(s)`);
|
|
1247
|
+
* }
|
|
1248
|
+
* }
|
|
1249
|
+
* ```
|
|
1250
|
+
*/
|
|
1251
|
+
var ChannelMenuHandler = class extends SelectMenuHandler {
|
|
1184
1252
|
/** The channels this select picked. */
|
|
1185
1253
|
get channels() {
|
|
1186
|
-
return this.
|
|
1254
|
+
return this.event.channels;
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
/**
|
|
1258
|
+
* Base class for a mentionable select menu handler.
|
|
1259
|
+
*
|
|
1260
|
+
* A mentionable menu accepts users and roles together. `this.users`, `this.members`, and `this.roles`
|
|
1261
|
+
* can each come back empty.
|
|
1262
|
+
*
|
|
1263
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof InviteId]`.
|
|
1264
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1265
|
+
*
|
|
1266
|
+
* @example
|
|
1267
|
+
* ```ts
|
|
1268
|
+
* \@MentionableMenuRoute(InviteId)
|
|
1269
|
+
* class Invite extends MentionableMenuHandler<[typeof InviteId]> {
|
|
1270
|
+
* async execute() {
|
|
1271
|
+
* await this.update(`inviting ${this.users.size} user(s) and ${this.roles.size} role(s)`);
|
|
1272
|
+
* }
|
|
1273
|
+
* }
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
1276
|
+
var MentionableMenuHandler = class extends SelectMenuHandler {
|
|
1277
|
+
/** The users this select picked. */
|
|
1278
|
+
get users() {
|
|
1279
|
+
return this.event.users;
|
|
1280
|
+
}
|
|
1281
|
+
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1282
|
+
get members() {
|
|
1283
|
+
return this.event.members;
|
|
1284
|
+
}
|
|
1285
|
+
/** The roles this select picked. */
|
|
1286
|
+
get roles() {
|
|
1287
|
+
return this.event.roles;
|
|
1187
1288
|
}
|
|
1188
1289
|
};
|
|
1189
1290
|
|
|
@@ -1488,10 +1589,10 @@ function extractErrorResponse(error, core, origin) {
|
|
|
1488
1589
|
};
|
|
1489
1590
|
}
|
|
1490
1591
|
reportRawFault(error, core, origin, uuid);
|
|
1491
|
-
const
|
|
1592
|
+
const Override = core.config.errors?.defaultError;
|
|
1492
1593
|
return {
|
|
1493
1594
|
uuid,
|
|
1494
|
-
response:
|
|
1595
|
+
response: Override ? new Override(uuid).render(ctx) : new Fault().render(ctx)
|
|
1495
1596
|
};
|
|
1496
1597
|
}
|
|
1497
1598
|
function reportFault(denial, core, origin, uuid) {
|
|
@@ -1743,12 +1844,12 @@ var EventDispatcher = class {
|
|
|
1743
1844
|
});
|
|
1744
1845
|
}
|
|
1745
1846
|
async runMiddlewares(eventName, args) {
|
|
1746
|
-
for (const { ctor, events } of this.middlewares) {
|
|
1847
|
+
for (const { ctor: Middleware, events } of this.middlewares) {
|
|
1747
1848
|
if (events && !events.includes(eventName)) continue;
|
|
1748
1849
|
try {
|
|
1749
|
-
await new
|
|
1850
|
+
await new Middleware(args, this.core, eventName).execute();
|
|
1750
1851
|
} catch (caught) {
|
|
1751
|
-
handleEventFault(caught, String(eventName),
|
|
1852
|
+
handleEventFault(caught, String(eventName), Middleware.name, args, this.core);
|
|
1752
1853
|
return false;
|
|
1753
1854
|
}
|
|
1754
1855
|
}
|
|
@@ -1814,7 +1915,7 @@ var EventDispatcher = class {
|
|
|
1814
1915
|
this.draining = true;
|
|
1815
1916
|
}
|
|
1816
1917
|
drain(timeoutMs) {
|
|
1817
|
-
return
|
|
1918
|
+
return drainInFlight(this.inFlight, timeoutMs, this.logger, "Events");
|
|
1818
1919
|
}
|
|
1819
1920
|
async processEvent(eventName, args) {
|
|
1820
1921
|
const handlerEntries = this.eventMap.get(eventName);
|
|
@@ -1830,15 +1931,15 @@ var EventDispatcher = class {
|
|
|
1830
1931
|
await this.processHandler(eventName, entry.ctor, args);
|
|
1831
1932
|
}
|
|
1832
1933
|
}
|
|
1833
|
-
async processHandler(eventName,
|
|
1934
|
+
async processHandler(eventName, Ctor, args) {
|
|
1834
1935
|
try {
|
|
1835
|
-
this.logger.debug(`Processing ${paint.sky.bold(eventName)} with ${paint.mute(
|
|
1836
|
-
const handler = new
|
|
1936
|
+
this.logger.debug(`Processing ${paint.sky.bold(eventName)} with ${paint.mute(Ctor.name)}`);
|
|
1937
|
+
const handler = new Ctor(args, this.core, eventName);
|
|
1837
1938
|
const eventCtx = eventGateContext(eventName, args, this.core);
|
|
1838
|
-
await runHandlerGates(
|
|
1939
|
+
await runHandlerGates(Ctor, eventCtx);
|
|
1839
1940
|
await handler.execute();
|
|
1840
1941
|
} catch (caught) {
|
|
1841
|
-
handleEventFault(caught, String(eventName),
|
|
1942
|
+
handleEventFault(caught, String(eventName), Ctor.name, args, this.core);
|
|
1842
1943
|
}
|
|
1843
1944
|
}
|
|
1844
1945
|
};
|
|
@@ -1935,17 +2036,19 @@ var InteractionDispatcher = class {
|
|
|
1935
2036
|
core;
|
|
1936
2037
|
logger = new Logger("Interactions", { channel: "interactions" });
|
|
1937
2038
|
isInitialized = false;
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2039
|
+
maps = {
|
|
2040
|
+
[InteractionKind.Slash]: /* @__PURE__ */ new Map(),
|
|
2041
|
+
[InteractionKind.Button]: /* @__PURE__ */ new Map(),
|
|
2042
|
+
[InteractionKind.Modal]: /* @__PURE__ */ new Map(),
|
|
2043
|
+
[InteractionKind.StringMenu]: /* @__PURE__ */ new Map(),
|
|
2044
|
+
[InteractionKind.UserMenu]: /* @__PURE__ */ new Map(),
|
|
2045
|
+
[InteractionKind.RoleMenu]: /* @__PURE__ */ new Map(),
|
|
2046
|
+
[InteractionKind.ChannelMenu]: /* @__PURE__ */ new Map(),
|
|
2047
|
+
[InteractionKind.MentionableMenu]: /* @__PURE__ */ new Map(),
|
|
2048
|
+
[InteractionKind.MessageContextMenu]: /* @__PURE__ */ new Map(),
|
|
2049
|
+
[InteractionKind.UserContextMenu]: /* @__PURE__ */ new Map(),
|
|
2050
|
+
[InteractionKind.Autocomplete]: /* @__PURE__ */ new Map()
|
|
2051
|
+
};
|
|
1949
2052
|
handlerFiles = /* @__PURE__ */ new Map();
|
|
1950
2053
|
keysToIgnore = /* @__PURE__ */ new Set();
|
|
1951
2054
|
middlewares = [];
|
|
@@ -1955,19 +2058,6 @@ var InteractionDispatcher = class {
|
|
|
1955
2058
|
loadedHandlers = [];
|
|
1956
2059
|
loadedMiddlewares = [];
|
|
1957
2060
|
hmrHandler;
|
|
1958
|
-
routeTypes = [
|
|
1959
|
-
[InteractionRoutes.Slash, this.slashMap],
|
|
1960
|
-
[InteractionRoutes.Button, this.buttonMap],
|
|
1961
|
-
[InteractionRoutes.Modal, this.modalMap],
|
|
1962
|
-
[InteractionRoutes.StringMenu, this.stringSelectMap],
|
|
1963
|
-
[InteractionRoutes.UserMenu, this.userSelectMap],
|
|
1964
|
-
[InteractionRoutes.RoleMenu, this.roleSelectMap],
|
|
1965
|
-
[InteractionRoutes.ChannelMenu, this.channelSelectMap],
|
|
1966
|
-
[InteractionRoutes.MentionableMenu, this.mentionableSelectMap],
|
|
1967
|
-
[InteractionRoutes.MessageContextMenu, this.messageContextMenuMap],
|
|
1968
|
-
[InteractionRoutes.UserContextMenu, this.userContextMenuMap],
|
|
1969
|
-
[InteractionRoutes.Autocomplete, this.autocompleteMap]
|
|
1970
|
-
];
|
|
1971
2061
|
constructor(core) {
|
|
1972
2062
|
this.core = core;
|
|
1973
2063
|
const ignoredKeysFromConfig = hasKeys(this.core.config.bot.interactions, ["ignoreCustomIds"]) ? this.core.config.bot.interactions.ignoreCustomIds : void 0;
|
|
@@ -1990,22 +2080,17 @@ var InteractionDispatcher = class {
|
|
|
1990
2080
|
});
|
|
1991
2081
|
}
|
|
1992
2082
|
warnUnhandledRoutes(commandLeaves) {
|
|
1993
|
-
for (const route of commandLeaves) if (!this.
|
|
2083
|
+
for (const route of commandLeaves) if (!this.maps[InteractionKind.Slash].has(route)) this.logger.warn(`Slash route ${paint.sky.bold(route)} has no registered ${paint.bold("@SlashRoute")} handler.`);
|
|
1994
2084
|
}
|
|
1995
2085
|
warnUnhandledContextMenuRoutes(leaves) {
|
|
1996
|
-
for (const name of leaves.user) if (!this.
|
|
1997
|
-
for (const name of leaves.message) if (!this.
|
|
2086
|
+
for (const name of leaves.user) if (!this.maps[InteractionKind.UserContextMenu].has(name)) this.logger.warn(`User context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
|
|
2087
|
+
for (const name of leaves.message) if (!this.maps[InteractionKind.MessageContextMenu].has(name)) this.logger.warn(`Message context menu ${paint.sky.bold(name)} has no registered ${paint.bold("@ContextMenuRoute")} handler.`);
|
|
1998
2088
|
}
|
|
1999
2089
|
getArtifacts(handlerClass) {
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
routeType,
|
|
2005
|
-
routes: meta
|
|
2006
|
-
});
|
|
2007
|
-
}
|
|
2008
|
-
return artifacts;
|
|
2090
|
+
return interactionRoutesOf(handlerClass).map(([routeType, routes]) => ({
|
|
2091
|
+
routeType,
|
|
2092
|
+
routes
|
|
2093
|
+
}));
|
|
2009
2094
|
}
|
|
2010
2095
|
async init() {
|
|
2011
2096
|
if (this.isInitialized) return;
|
|
@@ -2033,17 +2118,17 @@ var InteractionDispatcher = class {
|
|
|
2033
2118
|
}, "debug");
|
|
2034
2119
|
if (this.loadedMiddlewares.length > 0) utils.block("Loaded middlewares", utils.entries(this.loadedMiddlewares), "debug");
|
|
2035
2120
|
utils.block("Loaded interaction handlers", [...utils.entries(this.loadedHandlers), ...utils.counts({
|
|
2036
|
-
slash: this.
|
|
2037
|
-
buttons: this.
|
|
2038
|
-
modals: this.
|
|
2039
|
-
"string selects": this.
|
|
2040
|
-
"user selects": this.
|
|
2041
|
-
"role selects": this.
|
|
2042
|
-
"channel selects": this.
|
|
2043
|
-
"mentionable selects": this.
|
|
2044
|
-
"message menus": this.
|
|
2045
|
-
"user menus": this.
|
|
2046
|
-
autocomplete: this.
|
|
2121
|
+
slash: this.maps[InteractionKind.Slash].size,
|
|
2122
|
+
buttons: this.maps[InteractionKind.Button].size,
|
|
2123
|
+
modals: this.maps[InteractionKind.Modal].size,
|
|
2124
|
+
"string selects": this.maps[InteractionKind.StringMenu].size,
|
|
2125
|
+
"user selects": this.maps[InteractionKind.UserMenu].size,
|
|
2126
|
+
"role selects": this.maps[InteractionKind.RoleMenu].size,
|
|
2127
|
+
"channel selects": this.maps[InteractionKind.ChannelMenu].size,
|
|
2128
|
+
"mentionable selects": this.maps[InteractionKind.MentionableMenu].size,
|
|
2129
|
+
"message menus": this.maps[InteractionKind.MessageContextMenu].size,
|
|
2130
|
+
"user menus": this.maps[InteractionKind.UserContextMenu].size,
|
|
2131
|
+
autocomplete: this.maps[InteractionKind.Autocomplete].size
|
|
2047
2132
|
})], "debug");
|
|
2048
2133
|
}
|
|
2049
2134
|
async loadHandlers(dir) {
|
|
@@ -2090,21 +2175,20 @@ var InteractionDispatcher = class {
|
|
|
2090
2175
|
registerHandler(handlerClass, relativePath) {
|
|
2091
2176
|
const from = formatFilePath(relativePath);
|
|
2092
2177
|
const writes = [];
|
|
2093
|
-
for (const [
|
|
2094
|
-
const
|
|
2095
|
-
if (
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
}
|
|
2178
|
+
for (const [kind, routes] of interactionRoutesOf(handlerClass)) for (const route of routes) {
|
|
2179
|
+
const existing = this.maps[kind].get(route);
|
|
2180
|
+
if (existing && existing !== handlerClass) throw new SeedcordError(SeedcordErrorCode.InteractionDuplicateRoute, [
|
|
2181
|
+
`${kind}:${route}`,
|
|
2182
|
+
`${existing.name} (${this.handlerFiles.get(existing) ?? "unknown file"})`,
|
|
2183
|
+
`${handlerClass.name} (${from})`
|
|
2184
|
+
]);
|
|
2185
|
+
writes.push({
|
|
2186
|
+
kind,
|
|
2187
|
+
route
|
|
2188
|
+
});
|
|
2105
2189
|
}
|
|
2106
2190
|
if (writes.length === 0) return;
|
|
2107
|
-
for (const
|
|
2191
|
+
for (const { kind, route } of writes) this.maps[kind].set(route, handlerClass);
|
|
2108
2192
|
this.handlerFiles.set(handlerClass, from);
|
|
2109
2193
|
if (this.loading) this.loadedHandlers.push({
|
|
2110
2194
|
name: handlerClass.name,
|
|
@@ -2116,18 +2200,7 @@ var InteractionDispatcher = class {
|
|
|
2116
2200
|
}
|
|
2117
2201
|
unregisterHandler(handlerClass, artifacts) {
|
|
2118
2202
|
this.handlerFiles.delete(handlerClass);
|
|
2119
|
-
|
|
2120
|
-
for (const { routeType, routes } of artifacts) {
|
|
2121
|
-
const map = this.routeTypes.find(([type]) => type === routeType)?.[1];
|
|
2122
|
-
if (map) routes.forEach((route) => map.delete(route));
|
|
2123
|
-
}
|
|
2124
|
-
return;
|
|
2125
|
-
}
|
|
2126
|
-
for (const [routeType, map] of this.routeTypes) {
|
|
2127
|
-
const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
|
|
2128
|
-
if (!areRoutes(meta)) continue;
|
|
2129
|
-
meta.forEach((route) => map.delete(route));
|
|
2130
|
-
}
|
|
2203
|
+
for (const { routeType, routes } of artifacts ?? this.getArtifacts(handlerClass)) for (const route of routes) this.maps[routeType].delete(route);
|
|
2131
2204
|
}
|
|
2132
2205
|
unregisterMiddleware(middlewareCtor) {
|
|
2133
2206
|
const index = this.middlewares.findIndex((entry) => entry.ctor === middlewareCtor);
|
|
@@ -2150,19 +2223,19 @@ var InteractionDispatcher = class {
|
|
|
2150
2223
|
this.draining = true;
|
|
2151
2224
|
}
|
|
2152
2225
|
drain(timeoutMs) {
|
|
2153
|
-
return
|
|
2226
|
+
return drainInFlight(this.inFlight, timeoutMs, this.logger, "Interactions");
|
|
2154
2227
|
}
|
|
2155
|
-
async handleCustomIdInteraction(interaction, kind
|
|
2228
|
+
async handleCustomIdInteraction(interaction, kind) {
|
|
2156
2229
|
if ([...this.keysToIgnore].some((matcher) => matcher.owns(interaction.customId))) return;
|
|
2157
2230
|
const prefix = prefixOf(interaction.customId);
|
|
2158
2231
|
if (!prefix) this.logger.warn(`${paint.sky.bold(kind)} has invalid customId: ${paint.mute(interaction.customId)}`);
|
|
2159
|
-
await this.processInteraction(interaction, kind, () => prefix
|
|
2232
|
+
await this.processInteraction(interaction, kind, () => prefix);
|
|
2160
2233
|
}
|
|
2161
|
-
async processInteraction(interaction, kind, extractKey,
|
|
2234
|
+
async processInteraction(interaction, kind, extractKey, fallback = UnhandledRepliable) {
|
|
2162
2235
|
const key = extractKey(interaction);
|
|
2163
2236
|
const startedAt = performance.now();
|
|
2164
2237
|
const queuedMs = queuedMsFor(interaction.id);
|
|
2165
|
-
const matched =
|
|
2238
|
+
const matched = this.maps[kind].get(key);
|
|
2166
2239
|
let routeId = `${kind}:${key || "unrouted"}`;
|
|
2167
2240
|
let reported = false;
|
|
2168
2241
|
const report = (outcome) => {
|
|
@@ -2210,7 +2283,7 @@ var InteractionDispatcher = class {
|
|
|
2210
2283
|
return new HandlerCtor(interaction, this.core, dispatch);
|
|
2211
2284
|
}
|
|
2212
2285
|
async runMiddlewares(interaction) {
|
|
2213
|
-
for (const { ctor } of this.middlewares) await new
|
|
2286
|
+
for (const { ctor: Middleware } of this.middlewares) await new Middleware(interaction, this.core).execute();
|
|
2214
2287
|
}
|
|
2215
2288
|
async gateRefusal(HandlerCtor, interaction, routeId) {
|
|
2216
2289
|
const monitor = slowGateMonitor();
|
|
@@ -2263,38 +2336,38 @@ var InteractionDispatcher = class {
|
|
|
2263
2336
|
}
|
|
2264
2337
|
async handleSlashCommand(interaction) {
|
|
2265
2338
|
const route = slashRouteOf(interaction);
|
|
2266
|
-
await this.processInteraction(interaction,
|
|
2339
|
+
await this.processInteraction(interaction, InteractionKind.Slash, () => route);
|
|
2267
2340
|
}
|
|
2268
2341
|
async handleButton(interaction) {
|
|
2269
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2342
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.Button);
|
|
2270
2343
|
}
|
|
2271
2344
|
async handleModal(interaction) {
|
|
2272
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2345
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.Modal);
|
|
2273
2346
|
}
|
|
2274
2347
|
async handleStringSelectMenu(interaction) {
|
|
2275
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2348
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.StringMenu);
|
|
2276
2349
|
}
|
|
2277
2350
|
async handleUserSelectMenu(interaction) {
|
|
2278
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2351
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.UserMenu);
|
|
2279
2352
|
}
|
|
2280
2353
|
async handleRoleSelectMenu(interaction) {
|
|
2281
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2354
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.RoleMenu);
|
|
2282
2355
|
}
|
|
2283
2356
|
async handleChannelSelectMenu(interaction) {
|
|
2284
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2357
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.ChannelMenu);
|
|
2285
2358
|
}
|
|
2286
2359
|
async handleMentionableSelectMenu(interaction) {
|
|
2287
|
-
await this.handleCustomIdInteraction(interaction,
|
|
2360
|
+
await this.handleCustomIdInteraction(interaction, InteractionKind.MentionableMenu);
|
|
2288
2361
|
}
|
|
2289
2362
|
async handleMessageContextMenu(interaction) {
|
|
2290
|
-
await this.processInteraction(interaction,
|
|
2363
|
+
await this.processInteraction(interaction, InteractionKind.MessageContextMenu, () => interaction.commandName);
|
|
2291
2364
|
}
|
|
2292
2365
|
async handleUserContextMenu(interaction) {
|
|
2293
|
-
await this.processInteraction(interaction,
|
|
2366
|
+
await this.processInteraction(interaction, InteractionKind.UserContextMenu, () => interaction.commandName);
|
|
2294
2367
|
}
|
|
2295
2368
|
async handleAutocomplete(interaction) {
|
|
2296
2369
|
const route = slashRouteOf(interaction);
|
|
2297
|
-
await this.processInteraction(interaction,
|
|
2370
|
+
await this.processInteraction(interaction, InteractionKind.Autocomplete, () => route, UnhandledAutocomplete);
|
|
2298
2371
|
}
|
|
2299
2372
|
};
|
|
2300
2373
|
|
|
@@ -2323,8 +2396,6 @@ function __decorate(decorators, target, key, desc) {
|
|
|
2323
2396
|
|
|
2324
2397
|
//#endregion
|
|
2325
2398
|
//#region src/bot/Bot.ts
|
|
2326
|
-
const DISPATCH_DRAIN_TIMEOUT_MS = 5e3;
|
|
2327
|
-
const DRAIN_TASK_TIMEOUT_MS = 6e3;
|
|
2328
2399
|
const UNBIND_TIMEOUT_MS = 2e3;
|
|
2329
2400
|
const LOGOUT_TIMEOUT_MS = 2e3;
|
|
2330
2401
|
const loggerSlot = Symbol("seedcord:bot:logger");
|
|
@@ -2387,7 +2458,7 @@ var Bot = class {
|
|
|
2387
2458
|
this.#events?.stopAccepting();
|
|
2388
2459
|
}
|
|
2389
2460
|
async #drain() {
|
|
2390
|
-
await Promise.allSettled([this.#interactions?.drain(
|
|
2461
|
+
await Promise.allSettled([this.#interactions?.drain(DRAIN_WINDOW_MS), this.#events?.drain(DRAIN_WINDOW_MS)]);
|
|
2391
2462
|
}
|
|
2392
2463
|
/** @internal */
|
|
2393
2464
|
async [initSlot]() {
|
|
@@ -2437,7 +2508,7 @@ function initBot(bot) {
|
|
|
2437
2508
|
//#endregion
|
|
2438
2509
|
//#region src/version.ts
|
|
2439
2510
|
/** Package version */
|
|
2440
|
-
const version = "0.
|
|
2511
|
+
const version = "0.5.1";
|
|
2441
2512
|
|
|
2442
2513
|
//#endregion
|
|
2443
2514
|
//#region src/Seedcord.ts
|
|
@@ -2473,7 +2544,7 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
2473
2544
|
* @throws A **SeedcordError** When attempting to create multiple instances (singleton)
|
|
2474
2545
|
*/
|
|
2475
2546
|
constructor(config) {
|
|
2476
|
-
super(new CoordinatedShutdown(), new CoordinatedStartup());
|
|
2547
|
+
super(new CoordinatedShutdown(config.lifecycle?.shutdownDeadline), new CoordinatedStartup());
|
|
2477
2548
|
this.config = config;
|
|
2478
2549
|
installNodeDefaults(config.logger);
|
|
2479
2550
|
setBotColor(config.botColor);
|
|
@@ -2541,5 +2612,5 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
2541
2612
|
};
|
|
2542
2613
|
|
|
2543
2614
|
//#endregion
|
|
2544
|
-
export { ArraySource, AutocompleteHandler, BaseHandler, ButtonHandler, ComponentHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, GatewayEmoji, IgnoreBots, InteractionHandler, InteractionMiddleware, MessageContextMenuHandler, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator, Plugin, RegisterEvent, RepliableHandler, ReplySender, Seedcord, SelectMenuHandler, SlashHandler, Subscriber, UserContextMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, checkBotPermissions, checkPermissions, getConfirmation, hasPermsToAssign, version };
|
|
2615
|
+
export { ArraySource, AutocompleteHandler, BaseHandler, ButtonHandler, ChannelMenuHandler, ComponentHandler, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, GatewayEmoji, IgnoreBots, InteractionHandler, InteractionMiddleware, MentionableMenuHandler, MessageContextMenuHandler, Middleware, MiddlewareType, ModalHandler, Nsfw, Paginator, Plugin, RegisterEvent, RepliableHandler, ReplySender, RoleMenuHandler, Seedcord, SelectMenuHandler, SlashHandler, StringMenuHandler, Subscriber, UserContextMenuHandler, UserMenuHandler, WebhookLog, WinstonConsoleSink, WinstonFileSink, checkBotPermissions, checkPermissions, getConfirmation, hasPermsToAssign, version };
|
|
2545
2616
|
//# sourceMappingURL=index.mjs.map
|