seedcord 0.16.0-next.3 → 0.16.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +169 -625
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +680 -1129
- package/dist/index.mjs +128 -586
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -6
package/dist/index.cjs
CHANGED
|
@@ -27,11 +27,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
29
|
require("reflect-metadata");
|
|
30
|
+
let _seedcord_core = require("@seedcord/core");
|
|
31
|
+
let _seedcord_core_internal = require("@seedcord/core/internal");
|
|
32
|
+
let discord_js = require("discord.js");
|
|
30
33
|
let _seedcord_errors = require("@seedcord/errors");
|
|
31
34
|
let _seedcord_errors_internal = require("@seedcord/errors/internal");
|
|
32
|
-
let discord_js = require("discord.js");
|
|
33
|
-
let _seedcord_core_internal = require("@seedcord/core/internal");
|
|
34
|
-
let _seedcord_core = require("@seedcord/core");
|
|
35
35
|
let _seedcord_utils = require("@seedcord/utils");
|
|
36
36
|
let _seedcord_services = require("@seedcord/services");
|
|
37
37
|
let chalk = require("chalk");
|
|
@@ -41,60 +41,12 @@ let _seedcord_utils_internal = require("@seedcord/utils/internal");
|
|
|
41
41
|
let node_fs = require("node:fs");
|
|
42
42
|
let node_path = require("node:path");
|
|
43
43
|
let node_url = require("node:url");
|
|
44
|
+
let _seedcord_rate_limiter = require("@seedcord/rate-limiter");
|
|
44
45
|
let _seedcord_types_internal = require("@seedcord/types/internal");
|
|
45
46
|
let envapt = require("envapt");
|
|
46
47
|
let node_crypto = require("node:crypto");
|
|
47
48
|
node_crypto = __toESM(node_crypto, 1);
|
|
48
49
|
|
|
49
|
-
//#region src/metadataKeys.ts
|
|
50
|
-
/** @internal */
|
|
51
|
-
const InteractionMetadataKey = Symbol("seedcord:interaction:metadata");
|
|
52
|
-
/** @internal */
|
|
53
|
-
const InteractionRouteKeys = {
|
|
54
|
-
["slash"]: Symbol("seedcord:interaction:slash"),
|
|
55
|
-
["button"]: Symbol("seedcord:interaction:button"),
|
|
56
|
-
["modal"]: Symbol("seedcord:interaction:modal"),
|
|
57
|
-
["stringMenu"]: Symbol("seedcord:interaction:stringMenu"),
|
|
58
|
-
["userMenu"]: Symbol("seedcord:interaction:userMenu"),
|
|
59
|
-
["roleMenu"]: Symbol("seedcord:interaction:roleMenu"),
|
|
60
|
-
["channelMenu"]: Symbol("seedcord:interaction:channelMenu"),
|
|
61
|
-
["mentionableMenu"]: Symbol("seedcord:interaction:mentionableMenu"),
|
|
62
|
-
["messageContextMenu"]: Symbol("seedcord:interaction:messageContextMenu"),
|
|
63
|
-
["userContextMenu"]: Symbol("seedcord:interaction:userContextMenu"),
|
|
64
|
-
["autocomplete"]: Symbol("seedcord:interaction:autocomplete")
|
|
65
|
-
};
|
|
66
|
-
/** @internal */
|
|
67
|
-
const MiddlewareMetadataKey = Symbol("seedcord:middleware:metadata");
|
|
68
|
-
/** @internal */
|
|
69
|
-
const EventMetadataKey = Symbol("seedcord:event:metadata");
|
|
70
|
-
/** @internal */
|
|
71
|
-
const CommandMetadataKey = Symbol("seedcord:command:metadata");
|
|
72
|
-
/** @internal */
|
|
73
|
-
const GatedMetadataKey = Symbol("seedcord:gated:metadata");
|
|
74
|
-
/** @internal */
|
|
75
|
-
const SubscribeMetadataKey = Symbol("seedcord:subscribe:metadata");
|
|
76
|
-
|
|
77
|
-
//#endregion
|
|
78
|
-
//#region src/bot/decorators/Command.ts
|
|
79
|
-
function RegisterCommand(scope, guilds = []) {
|
|
80
|
-
return (ctor) => {
|
|
81
|
-
const meta = scope === "global" ? { scope } : {
|
|
82
|
-
scope,
|
|
83
|
-
guilds
|
|
84
|
-
};
|
|
85
|
-
const existingMeta = Reflect.getOwnMetadata(CommandMetadataKey, ctor);
|
|
86
|
-
if (existingMeta) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandAlreadyRegistered, [
|
|
87
|
-
ctor.name,
|
|
88
|
-
existingMeta.scope,
|
|
89
|
-
scope
|
|
90
|
-
]);
|
|
91
|
-
if (scope === "global" && guilds.length > 0) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandGlobalWithGuilds);
|
|
92
|
-
if (scope === "guild" && (!Array.isArray(guilds) || guilds.length === 0)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandGuildWithoutGuilds);
|
|
93
|
-
Reflect.defineMetadata(CommandMetadataKey, meta, ctor);
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
//#endregion
|
|
98
50
|
//#region src/bot/decorators/Events.ts
|
|
99
51
|
/**
|
|
100
52
|
* Registers an event handler class with one or more Discord.js events.
|
|
@@ -138,126 +90,12 @@ function RegisterCommand(scope, guilds = []) {
|
|
|
138
90
|
*/
|
|
139
91
|
function RegisterEvent(...defs) {
|
|
140
92
|
return function(constructor) {
|
|
141
|
-
const existing = Reflect.getMetadata(EventMetadataKey, constructor) ?? [];
|
|
93
|
+
const existing = Reflect.getMetadata(_seedcord_core_internal.EventMetadataKey, constructor) ?? [];
|
|
142
94
|
const entries = defs.map(([event, options]) => ({
|
|
143
95
|
event,
|
|
144
96
|
frequency: options?.frequency ?? "on"
|
|
145
97
|
}));
|
|
146
|
-
Reflect.defineMetadata(EventMetadataKey, [...existing, ...entries], constructor);
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
//#endregion
|
|
151
|
-
//#region src/miscellaneous/deriveEventActor.ts
|
|
152
|
-
function deriveEventActor(args) {
|
|
153
|
-
const tuple = Array.isArray(args) ? args : [args];
|
|
154
|
-
for (const arg of tuple) {
|
|
155
|
-
if (arg instanceof discord_js.Message) return {
|
|
156
|
-
guild: arg.guild,
|
|
157
|
-
member: arg.member,
|
|
158
|
-
user: arg.author,
|
|
159
|
-
channelId: arg.channelId
|
|
160
|
-
};
|
|
161
|
-
if (arg instanceof discord_js.GuildMember) return {
|
|
162
|
-
guild: arg.guild,
|
|
163
|
-
member: arg,
|
|
164
|
-
user: arg.user,
|
|
165
|
-
channelId: null
|
|
166
|
-
};
|
|
167
|
-
if (arg instanceof discord_js.User) return {
|
|
168
|
-
guild: null,
|
|
169
|
-
member: null,
|
|
170
|
-
user: arg,
|
|
171
|
-
channelId: null
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
guild: null,
|
|
176
|
-
member: null,
|
|
177
|
-
user: null,
|
|
178
|
-
channelId: null
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
//#endregion
|
|
183
|
-
//#region src/bot/gates/effects.ts
|
|
184
|
-
const commitQueues = /* @__PURE__ */ new WeakMap();
|
|
185
|
-
function isEffectGate(gate) {
|
|
186
|
-
return typeof gate.check === "function" && typeof gate.commit === "function";
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Runs a gate's check and, when it passes and carries an effect, queues its commit against the context. A
|
|
190
|
-
* refusal throws here before the queue, so a refused effect gate never commits. The combinators and the
|
|
191
|
-
* runner both go through this, so an effect gate inside `and`/`or` queues the same way a top-level one does.
|
|
192
|
-
*/
|
|
193
|
-
async function runCheck(gate, ctx) {
|
|
194
|
-
await gate.check(ctx);
|
|
195
|
-
if (!isEffectGate(gate)) return;
|
|
196
|
-
let queue = commitQueues.get(ctx);
|
|
197
|
-
if (!queue) {
|
|
198
|
-
queue = [];
|
|
199
|
-
commitQueues.set(ctx, queue);
|
|
200
|
-
}
|
|
201
|
-
queue.push(() => gate.commit(ctx));
|
|
202
|
-
}
|
|
203
|
-
/** Drains the queued commits once the whole set has passed. */
|
|
204
|
-
async function runCommits(ctx) {
|
|
205
|
-
const queue = commitQueues.get(ctx);
|
|
206
|
-
if (!queue) return;
|
|
207
|
-
for (const commit of queue) await commit();
|
|
208
|
-
}
|
|
209
|
-
/** Drops a context's queue. The runner calls this after every run, so a refused or drained run leaves no stale queue behind. */
|
|
210
|
-
function discardCommits(ctx) {
|
|
211
|
-
commitQueues.delete(ctx);
|
|
212
|
-
}
|
|
213
|
-
/** The current queued-commit count, a mark an `or` arm rolls back to if it refuses. */
|
|
214
|
-
function markCommits(ctx) {
|
|
215
|
-
return commitQueues.get(ctx)?.length ?? 0;
|
|
216
|
-
}
|
|
217
|
-
/** Drops commits queued after `mark`, so an `or` arm that queued an effect then refused leaves nothing for the winning arm to carry. */
|
|
218
|
-
function rollbackCommits(ctx, mark) {
|
|
219
|
-
const queue = commitQueues.get(ctx);
|
|
220
|
-
if (queue && queue.length > mark) queue.length = mark;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
//#endregion
|
|
224
|
-
//#region src/bot/gates/runGates.ts
|
|
225
|
-
/**
|
|
226
|
-
* Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect
|
|
227
|
-
* gate's commit runs once the whole set passes.
|
|
228
|
-
*/
|
|
229
|
-
async function runGates(gates, ctx) {
|
|
230
|
-
try {
|
|
231
|
-
for (const gate of gates) await runCheck(gate, ctx);
|
|
232
|
-
await runCommits(ctx);
|
|
233
|
-
} finally {
|
|
234
|
-
discardCommits(ctx);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function interactionGateContext(interaction, core) {
|
|
238
|
-
return {
|
|
239
|
-
kind: "interaction",
|
|
240
|
-
interaction,
|
|
241
|
-
core,
|
|
242
|
-
user: interaction.user,
|
|
243
|
-
guild: interaction.guild,
|
|
244
|
-
member: interaction.member instanceof discord_js.GuildMember ? interaction.member : null,
|
|
245
|
-
guildId: interaction.guildId,
|
|
246
|
-
channelId: interaction.channelId
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
function eventGateContext(eventName, args, core) {
|
|
250
|
-
const actor = deriveEventActor(args);
|
|
251
|
-
return {
|
|
252
|
-
kind: "event",
|
|
253
|
-
core,
|
|
254
|
-
eventName,
|
|
255
|
-
payload: args,
|
|
256
|
-
user: actor.user,
|
|
257
|
-
guild: actor.guild,
|
|
258
|
-
member: actor.member,
|
|
259
|
-
guildId: actor.guild?.id ?? null,
|
|
260
|
-
channelId: actor.channelId
|
|
98
|
+
Reflect.defineMetadata(_seedcord_core_internal.EventMetadataKey, [...existing, ...entries], constructor);
|
|
261
99
|
};
|
|
262
100
|
}
|
|
263
101
|
|
|
@@ -296,22 +134,10 @@ function eventGateContext(eventName, args, core) {
|
|
|
296
134
|
*/
|
|
297
135
|
function Gated(...gates) {
|
|
298
136
|
return function(ctor) {
|
|
299
|
-
const existing = Reflect.getMetadata(GatedMetadataKey, ctor) ?? [];
|
|
300
|
-
Reflect.defineMetadata(GatedMetadataKey, [...existing, ...gates], ctor);
|
|
137
|
+
const existing = Reflect.getMetadata(_seedcord_core_internal.GatedMetadataKey, ctor) ?? [];
|
|
138
|
+
Reflect.defineMetadata(_seedcord_core_internal.GatedMetadataKey, [...existing, ...gates], ctor);
|
|
301
139
|
};
|
|
302
140
|
}
|
|
303
|
-
/**
|
|
304
|
-
* Runs the gates a handler was decorated with against the given context. The dispatcher calls this before
|
|
305
|
-
* `execute`, inside the boundary, so a refusal renders or drops.
|
|
306
|
-
*
|
|
307
|
-
* @param handlerCtor - The handler class whose attached gates are read from metadata.
|
|
308
|
-
* @param ctx - The context passed to each gate, supplying what the gate checks against.
|
|
309
|
-
*/
|
|
310
|
-
async function runHandlerGates(handlerCtor, ctx) {
|
|
311
|
-
const gates = Reflect.getMetadata(GatedMetadataKey, handlerCtor);
|
|
312
|
-
if (!gates) return;
|
|
313
|
-
await runGates(gates, ctx);
|
|
314
|
-
}
|
|
315
141
|
|
|
316
142
|
//#endregion
|
|
317
143
|
//#region src/miscellaneous/areRoutes.ts
|
|
@@ -368,7 +194,7 @@ let SelectMenuKind = /* @__PURE__ */ function(SelectMenuKind) {
|
|
|
368
194
|
*/
|
|
369
195
|
function SlashRoute(...routes) {
|
|
370
196
|
return function(constructor) {
|
|
371
|
-
storeMetadata(
|
|
197
|
+
storeMetadata(_seedcord_core_internal.InteractionRoutes.Slash, routes, constructor);
|
|
372
198
|
};
|
|
373
199
|
}
|
|
374
200
|
/**
|
|
@@ -384,7 +210,7 @@ function SlashRoute(...routes) {
|
|
|
384
210
|
*/
|
|
385
211
|
function ButtonRoute(...defs) {
|
|
386
212
|
return function(constructor) {
|
|
387
|
-
storeComponentRoute(
|
|
213
|
+
storeComponentRoute(_seedcord_core_internal.InteractionRoutes.Button, defs, constructor);
|
|
388
214
|
};
|
|
389
215
|
}
|
|
390
216
|
/**
|
|
@@ -400,7 +226,7 @@ function ButtonRoute(...defs) {
|
|
|
400
226
|
*/
|
|
401
227
|
function ModalRoute(...defs) {
|
|
402
228
|
return function(constructor) {
|
|
403
|
-
storeComponentRoute(
|
|
229
|
+
storeComponentRoute(_seedcord_core_internal.InteractionRoutes.Modal, defs, constructor);
|
|
404
230
|
};
|
|
405
231
|
}
|
|
406
232
|
/**
|
|
@@ -426,7 +252,7 @@ function ModalRoute(...defs) {
|
|
|
426
252
|
*/
|
|
427
253
|
function ContextMenuRoute(kind, ...names) {
|
|
428
254
|
return function(constructor) {
|
|
429
|
-
storeMetadata(kind === discord_js.ApplicationCommandType.User ?
|
|
255
|
+
storeMetadata(kind === discord_js.ApplicationCommandType.User ? _seedcord_core_internal.InteractionRoutes.UserContextMenu : _seedcord_core_internal.InteractionRoutes.MessageContextMenu, names, constructor);
|
|
430
256
|
};
|
|
431
257
|
}
|
|
432
258
|
/**
|
|
@@ -451,7 +277,7 @@ function ContextMenuRoute(kind, ...names) {
|
|
|
451
277
|
*/
|
|
452
278
|
function AutocompleteRoute(...routes) {
|
|
453
279
|
return function(constructor) {
|
|
454
|
-
storeMetadata(
|
|
280
|
+
storeMetadata(_seedcord_core_internal.InteractionRoutes.Autocomplete, routes, constructor);
|
|
455
281
|
};
|
|
456
282
|
}
|
|
457
283
|
/**
|
|
@@ -476,11 +302,11 @@ function AutocompleteRoute(...routes) {
|
|
|
476
302
|
function SelectMenuRoute(type, ...defs) {
|
|
477
303
|
return function(constructor) {
|
|
478
304
|
storeComponentRoute({
|
|
479
|
-
["string"]:
|
|
480
|
-
["user"]:
|
|
481
|
-
["role"]:
|
|
482
|
-
["channel"]:
|
|
483
|
-
["mentionable"]:
|
|
305
|
+
["string"]: _seedcord_core_internal.InteractionRoutes.StringMenu,
|
|
306
|
+
["user"]: _seedcord_core_internal.InteractionRoutes.UserMenu,
|
|
307
|
+
["role"]: _seedcord_core_internal.InteractionRoutes.RoleMenu,
|
|
308
|
+
["channel"]: _seedcord_core_internal.InteractionRoutes.ChannelMenu,
|
|
309
|
+
["mentionable"]: _seedcord_core_internal.InteractionRoutes.MentionableMenu
|
|
484
310
|
}[type], defs, constructor);
|
|
485
311
|
};
|
|
486
312
|
}
|
|
@@ -489,12 +315,12 @@ function storeComponentRoute(route, defs, constructor) {
|
|
|
489
315
|
Reflect.defineMetadata(_seedcord_core_internal.ComponentDefsKey, defs, constructor);
|
|
490
316
|
}
|
|
491
317
|
function storeMetadata(route, routes, constructor) {
|
|
492
|
-
const key = InteractionRouteKeys[route];
|
|
318
|
+
const key = _seedcord_core_internal.InteractionRouteKeys[route];
|
|
493
319
|
const savedRoutes = Reflect.getMetadata(key, constructor);
|
|
494
320
|
const existing = areRoutes(savedRoutes) ? savedRoutes : [];
|
|
495
321
|
const toStore = Array.isArray(routes) ? routes : [routes];
|
|
496
322
|
Reflect.defineMetadata(key, [...existing, ...toStore], constructor);
|
|
497
|
-
Reflect.defineMetadata(InteractionMetadataKey, true, constructor);
|
|
323
|
+
Reflect.defineMetadata(_seedcord_core_internal.InteractionMetadataKey, true, constructor);
|
|
498
324
|
}
|
|
499
325
|
|
|
500
326
|
//#endregion
|
|
@@ -536,111 +362,34 @@ function Middleware(type, priority = 0, options = {}) {
|
|
|
536
362
|
type,
|
|
537
363
|
...options.events && options.events.length > 0 && { events: options.events }
|
|
538
364
|
};
|
|
539
|
-
Reflect.defineMetadata(MiddlewareMetadataKey, metadata, ctor);
|
|
365
|
+
Reflect.defineMetadata(_seedcord_core_internal.MiddlewareMetadataKey, metadata, ctor);
|
|
540
366
|
};
|
|
541
367
|
}
|
|
542
368
|
|
|
543
369
|
//#endregion
|
|
544
|
-
//#region src/bot/gates/
|
|
370
|
+
//#region src/bot/gates/catalog/IgnoreBots.ts
|
|
545
371
|
/**
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
* the
|
|
549
|
-
* handler.
|
|
550
|
-
*
|
|
551
|
-
* @typeParam Name - The gate's name captured as a literal, so a mismatch error can name the gate.
|
|
552
|
-
* @typeParam Ctx - The context the check reads, inferred from the `ctx` annotation.
|
|
553
|
-
*
|
|
554
|
-
* @param name - The gate's name, used in mismatch errors.
|
|
555
|
-
* @param fn - The check, which refuses by throwing a Notice or a Silence and passes by returning.
|
|
372
|
+
* Drops a client event whose actor is a bot, with a {@link Silence} so nothing is replied. Event-only, because a
|
|
373
|
+
* Silence on an interaction would leave Discord's failed-interaction state. It rejects an interaction handler at
|
|
374
|
+
* the decorator line. Takes no options, so attach it directly without calling it.
|
|
556
375
|
*
|
|
557
|
-
* @see {@link defineEffectGate}
|
|
558
376
|
* @see {@link Gated}
|
|
559
377
|
*
|
|
560
378
|
* @example
|
|
561
379
|
* ```ts
|
|
562
|
-
* // a gate factory that takes its own option and closes over it
|
|
563
|
-
* function MinRoleCount(min: number): Gate<InteractionGateContext, 'MinRoleCount'> {
|
|
564
|
-
* return defineGate('MinRoleCount', (ctx: InteractionGateContext) => {
|
|
565
|
-
* if (ctx.member && ctx.member.roles.cache.size < min) throw new NotEnoughRoles(min);
|
|
566
|
-
* });
|
|
567
|
-
* }
|
|
568
|
-
* ```
|
|
569
|
-
*
|
|
570
|
-
* @example
|
|
571
|
-
* ```ts
|
|
572
|
-
* // agnostic gate (no ctx annotation): fits any handler
|
|
573
|
-
* const Owner = defineGate('owner', (ctx) => {
|
|
574
|
-
* if (!ctx.user) throw new NotOwner();
|
|
575
|
-
* });
|
|
576
|
-
* ```
|
|
577
|
-
*
|
|
578
|
-
* @example
|
|
579
|
-
* ```ts
|
|
580
|
-
* // interaction-only gate: annotate ctx to narrow the required context
|
|
581
|
-
* const SlashGate = defineGate('slash', (ctx: InteractionGateContext) => {
|
|
582
|
-
* void ctx.interaction;
|
|
583
|
-
* });
|
|
584
|
-
* ```
|
|
585
|
-
*
|
|
586
|
-
* @example
|
|
587
|
-
* ```ts
|
|
588
380
|
* import { Events } from 'discord.js';
|
|
589
381
|
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*/
|
|
596
|
-
function defineGate(name, fn) {
|
|
597
|
-
return {
|
|
598
|
-
name,
|
|
599
|
-
check: async (ctx) => fn(ctx)
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Builds an {@link EffectGate} from a `check` and a `commit`. `check` peeks and refuses by throwing, and
|
|
604
|
-
* `commit` applies the side effect, running only once the whole gate set passes so a later refusal never
|
|
605
|
-
* commits. In an `or`, a refusing arm's queued commit is rolled back. This is how {@link Cooldown} peeks
|
|
606
|
-
* in `check` and charges the slot in `commit`.
|
|
607
|
-
*
|
|
608
|
-
* @typeParam Name - The gate's name captured as a literal, so a mismatch error can name the gate.
|
|
609
|
-
* @typeParam Ctx - The context both `check` and `commit` read, inferred from the `ctx` annotation.
|
|
610
|
-
*
|
|
611
|
-
* @param name - The gate's name, used in mismatch errors.
|
|
612
|
-
* @param check - Peeks and refuses by throwing, without applying the side effect.
|
|
613
|
-
* @param commit - Applies the side effect, running only after the whole gate set passes.
|
|
614
|
-
*
|
|
615
|
-
* @see {@link defineGate}
|
|
616
|
-
* @see {@link Gated}
|
|
617
|
-
* @see {@link Cooldown}
|
|
618
|
-
*
|
|
619
|
-
* @example
|
|
620
|
-
* ```ts
|
|
621
|
-
* // an effect-gate factory that takes its own limit and closes over it
|
|
622
|
-
* function UsesPerDay(max: number): EffectGate<GateContextBase, 'UsesPerDay'> {
|
|
623
|
-
* return defineEffectGate(
|
|
624
|
-
* 'UsesPerDay',
|
|
625
|
-
* (ctx) => {
|
|
626
|
-
* // peek and refuse by throwing, do not mutate yet
|
|
627
|
-
* if (usedToday(ctx.user) >= max) throw new OutOfUsesNotice(max);
|
|
628
|
-
* },
|
|
629
|
-
* (ctx) => {
|
|
630
|
-
* // runs only after the whole gate set passes
|
|
631
|
-
* recordUse(ctx.user);
|
|
632
|
-
* }
|
|
633
|
-
* );
|
|
382
|
+
* \@Gated(IgnoreBots)
|
|
383
|
+
* class OnMessage extends EventHandler<Events.MessageCreate> {
|
|
384
|
+
* async execute() {
|
|
385
|
+
* // ...
|
|
386
|
+
* }
|
|
634
387
|
* }
|
|
635
388
|
* ```
|
|
636
389
|
*/
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
check: async (ctx) => check(ctx),
|
|
641
|
-
commit: async (ctx) => commit(ctx)
|
|
642
|
-
};
|
|
643
|
-
}
|
|
390
|
+
const IgnoreBots = (0, _seedcord_core.defineGate)("IgnoreBots", (ctx) => {
|
|
391
|
+
if (ctx.user?.bot) throw new _seedcord_core.Silence("actor is a bot");
|
|
392
|
+
});
|
|
644
393
|
|
|
645
394
|
//#endregion
|
|
646
395
|
//#region src/bot/notices/utils.ts
|
|
@@ -659,63 +408,18 @@ function labelFor(subject) {
|
|
|
659
408
|
|
|
660
409
|
//#endregion
|
|
661
410
|
//#region src/bot/notices/index.ts
|
|
662
|
-
var
|
|
663
|
-
render() {
|
|
664
|
-
return { components: [new _seedcord_core_internal.NoticeCard(this.message).component] };
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
var NotOwner = class extends GateNotice {
|
|
668
|
-
constructor(message = "Only the bot owner can use this.") {
|
|
669
|
-
super(message);
|
|
670
|
-
}
|
|
671
|
-
};
|
|
672
|
-
var NotInGuild = class extends GateNotice {
|
|
673
|
-
constructor(message = "This can only be used in a server.") {
|
|
674
|
-
super(message);
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
var NotInDm = class extends GateNotice {
|
|
678
|
-
constructor(message = "This can only be used in a direct message.") {
|
|
679
|
-
super(message);
|
|
680
|
-
}
|
|
681
|
-
};
|
|
682
|
-
var NotNsfw = class extends GateNotice {
|
|
411
|
+
var NotNsfw = class extends _seedcord_core_internal.GateNotice {
|
|
683
412
|
constructor(message = "This can only be used in an age-restricted channel.") {
|
|
684
413
|
super(message);
|
|
685
414
|
}
|
|
686
415
|
};
|
|
687
|
-
var
|
|
688
|
-
expires;
|
|
689
|
-
constructor(expires, message) {
|
|
690
|
-
super(message ?? `You are doing that too fast. Try again <t:${(0, _seedcord_utils.toEpochSeconds)(expires)}:R>.`);
|
|
691
|
-
this.expires = expires;
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
var MissingRole = class extends GateNotice {
|
|
416
|
+
var MissingRole = class extends _seedcord_core_internal.GateNotice {
|
|
695
417
|
role;
|
|
696
418
|
constructor(message, role) {
|
|
697
419
|
super(message ?? (role ? `You need the ${role.name} role to use this.` : "You do not have the required role."));
|
|
698
420
|
this.role = role;
|
|
699
421
|
}
|
|
700
422
|
};
|
|
701
|
-
var NotAllowed = class extends _seedcord_core.Notice {
|
|
702
|
-
constructor() {
|
|
703
|
-
super("not allowed");
|
|
704
|
-
}
|
|
705
|
-
render() {
|
|
706
|
-
return { components: [new _seedcord_core_internal.NoticeCard("You are not allowed to use this command.").component] };
|
|
707
|
-
}
|
|
708
|
-
};
|
|
709
|
-
var NeedsAny = class extends _seedcord_core.Notice {
|
|
710
|
-
summaries;
|
|
711
|
-
constructor(summaries) {
|
|
712
|
-
super("not allowed");
|
|
713
|
-
this.summaries = summaries;
|
|
714
|
-
}
|
|
715
|
-
render() {
|
|
716
|
-
return { components: [new _seedcord_core_internal.NoticeCard(`You need any of:\n${this.summaries.map((summary) => `• ${summary}`).join("\n")}`).component] };
|
|
717
|
-
}
|
|
718
|
-
};
|
|
719
423
|
var RoleHigherThanMe = class extends _seedcord_core.Notice {
|
|
720
424
|
role;
|
|
721
425
|
botRole;
|
|
@@ -801,241 +505,6 @@ var CouldNotFindChannel = class extends _seedcord_core.Notice {
|
|
|
801
505
|
}
|
|
802
506
|
};
|
|
803
507
|
|
|
804
|
-
//#endregion
|
|
805
|
-
//#region src/bot/gates/combinators.ts
|
|
806
|
-
function and(...gates) {
|
|
807
|
-
return defineGate("and", async (ctx) => {
|
|
808
|
-
for (const gate of gates) await runCheck(gate, ctx);
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
function isOrOptions(arg) {
|
|
812
|
-
return !("check" in arg);
|
|
813
|
-
}
|
|
814
|
-
function or(...args) {
|
|
815
|
-
const last = args.at(-1);
|
|
816
|
-
const options = last !== void 0 && isOrOptions(last) ? last : void 0;
|
|
817
|
-
const gates = options ? args.slice(0, -1) : args;
|
|
818
|
-
return defineGate("or", async (ctx) => {
|
|
819
|
-
const summaries = [];
|
|
820
|
-
let everyArmHasSummary = true;
|
|
821
|
-
for (const gate of gates) {
|
|
822
|
-
const mark = markCommits(ctx);
|
|
823
|
-
try {
|
|
824
|
-
await runCheck(gate, ctx);
|
|
825
|
-
return;
|
|
826
|
-
} catch (error) {
|
|
827
|
-
if (error instanceof _seedcord_core.Notice && !error.report) {
|
|
828
|
-
rollbackCommits(ctx, mark);
|
|
829
|
-
if (error.summary === void 0) everyArmHasSummary = false;
|
|
830
|
-
else summaries.push(error.summary);
|
|
831
|
-
continue;
|
|
832
|
-
}
|
|
833
|
-
throw error;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
if (options) throw typeof options.fail === "function" ? options.fail(ctx) : options.fail;
|
|
837
|
-
if (everyArmHasSummary && summaries.length > 0) throw new NeedsAny(summaries);
|
|
838
|
-
throw new NotAllowed();
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
//#endregion
|
|
843
|
-
//#region src/bot/gates/catalog/options.ts
|
|
844
|
-
function pickNotice(options, makeDefault) {
|
|
845
|
-
return options?.notice ?? makeDefault(options?.message);
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
//#endregion
|
|
849
|
-
//#region src/bot/gates/catalog/access.ts
|
|
850
|
-
/**
|
|
851
|
-
* Passes only for a user id listed in `config.ownerIds`, else refuses.
|
|
852
|
-
*
|
|
853
|
-
* Agnostic, so it attaches to interaction and event handlers alike. With no `ownerIds` configured it refuses every caller. Pass {@link GateNoticeOptions} to reword or replace the refusal.
|
|
854
|
-
*
|
|
855
|
-
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
856
|
-
*
|
|
857
|
-
* @see {@link Gated}
|
|
858
|
-
*
|
|
859
|
-
* @example
|
|
860
|
-
* ```ts
|
|
861
|
-
* \@Gated(OwnerOnly())
|
|
862
|
-
* \@SlashRoute('shutdown')
|
|
863
|
-
* class ShutdownHandler extends SlashHandler<'shutdown'> {
|
|
864
|
-
* async execute() {
|
|
865
|
-
* // ...
|
|
866
|
-
* }
|
|
867
|
-
* }
|
|
868
|
-
* ```
|
|
869
|
-
*
|
|
870
|
-
* @example
|
|
871
|
-
* ```ts
|
|
872
|
-
* // reword the refusal, keeping the embed styling
|
|
873
|
-
* OwnerOnly({ message: 'Owners only.' });
|
|
874
|
-
* ```
|
|
875
|
-
*/
|
|
876
|
-
function OwnerOnly(options) {
|
|
877
|
-
return defineGate("OwnerOnly", (ctx) => {
|
|
878
|
-
const owners = ctx.core.config.ownerIds ?? [];
|
|
879
|
-
if (ctx.user && owners.includes(ctx.user.id)) return;
|
|
880
|
-
throw pickNotice(options, (message) => new NotOwner(message));
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
/**
|
|
884
|
-
* Passes inside a guild, else refuses.
|
|
885
|
-
*
|
|
886
|
-
* Agnostic, so it attaches to any handler kind. Often paired with {@link RequirePermissions} in an {@link and}.
|
|
887
|
-
*
|
|
888
|
-
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
889
|
-
*
|
|
890
|
-
* @see {@link Gated}
|
|
891
|
-
*
|
|
892
|
-
* @example
|
|
893
|
-
* ```ts
|
|
894
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
895
|
-
*
|
|
896
|
-
* \@Gated(GuildOnly(), RequirePermissions([PermissionFlagsBits.Administrator]))
|
|
897
|
-
* \@SlashRoute('maintenance')
|
|
898
|
-
* class Maintenance extends SlashHandler<'maintenance'> {
|
|
899
|
-
* async execute() {
|
|
900
|
-
* // ...
|
|
901
|
-
* }
|
|
902
|
-
* }
|
|
903
|
-
* ```
|
|
904
|
-
*/
|
|
905
|
-
function GuildOnly(options) {
|
|
906
|
-
return defineGate("GuildOnly", (ctx) => {
|
|
907
|
-
if (ctx.guild) return;
|
|
908
|
-
throw pickNotice(options, (message) => new NotInGuild(message));
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
/**
|
|
912
|
-
* Passes in a direct message, else refuses.
|
|
913
|
-
*
|
|
914
|
-
* Agnostic, so it attaches to any handler kind. The inverse of {@link GuildOnly}, so combining the two in an {@link and} can never pass.
|
|
915
|
-
*
|
|
916
|
-
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
917
|
-
*
|
|
918
|
-
* @see {@link Gated}
|
|
919
|
-
*
|
|
920
|
-
* @example
|
|
921
|
-
* ```ts
|
|
922
|
-
* \@Gated(DmOnly())
|
|
923
|
-
* \@SlashRoute('verify')
|
|
924
|
-
* class VerifyHandler extends SlashHandler<'verify'> {
|
|
925
|
-
* async execute() {
|
|
926
|
-
* // ...
|
|
927
|
-
* }
|
|
928
|
-
* }
|
|
929
|
-
* ```
|
|
930
|
-
*/
|
|
931
|
-
function DmOnly(options) {
|
|
932
|
-
return defineGate("DmOnly", (ctx) => {
|
|
933
|
-
if (!ctx.guild) return;
|
|
934
|
-
throw pickNotice(options, (message) => new NotInDm(message));
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
//#endregion
|
|
939
|
-
//#region src/bot/gates/catalog/Cooldown.ts
|
|
940
|
-
let bucketSeq = 0;
|
|
941
|
-
function scopeValue(ctx, per) {
|
|
942
|
-
if (per === "guild") return ctx.guildId ?? "global";
|
|
943
|
-
if (per === "channel") return ctx.channelId ?? "global";
|
|
944
|
-
return ctx.user?.id ?? "global";
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* Allows `limit` uses per window, scoped by `per`. A number `duration` is **seconds**, a string is
|
|
948
|
-
* a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError** at construction. The
|
|
949
|
-
* slot is charged in commit, only after the whole gate set passes, so a later refusal never burns the cooldown.
|
|
950
|
-
* Each call gets its own bucket, so two handlers never share a window. Reword the refusal with {@link CooldownOptions.message}
|
|
951
|
-
* or replace it with {@link CooldownOptions.notice}.
|
|
952
|
-
*
|
|
953
|
-
* @param duration - A number is seconds, a string is a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError**.
|
|
954
|
-
* @param options - Sets the scope with `per`, the uses per window with `limit`, and the refusal text with `message` or `notice`.
|
|
955
|
-
*
|
|
956
|
-
* @see {@link Gated}
|
|
957
|
-
* @see {@link RateLimiter}
|
|
958
|
-
*
|
|
959
|
-
* @example
|
|
960
|
-
* ```ts
|
|
961
|
-
* // a number argument is SECONDS
|
|
962
|
-
* \@Gated(Cooldown(5))
|
|
963
|
-
* \@SlashRoute('daily')
|
|
964
|
-
* class DailyHandler extends SlashHandler<'daily'> {
|
|
965
|
-
* async execute() {
|
|
966
|
-
* // ...
|
|
967
|
-
* }
|
|
968
|
-
* }
|
|
969
|
-
* ```
|
|
970
|
-
*
|
|
971
|
-
* @example
|
|
972
|
-
* ```ts
|
|
973
|
-
* // a string is a duration, here scoped per guild instead of per user
|
|
974
|
-
* Cooldown('30m', { per: 'guild' });
|
|
975
|
-
* ```
|
|
976
|
-
*
|
|
977
|
-
* @example
|
|
978
|
-
* ```ts
|
|
979
|
-
* // a burst, 3 uses per 10 minutes per user, then it refuses until a slot frees
|
|
980
|
-
* \@Gated(Cooldown('10m', { limit: 3 }))
|
|
981
|
-
* \@SlashRoute('report')
|
|
982
|
-
* class ReportHandler extends SlashHandler<'report'> {
|
|
983
|
-
* async execute() {
|
|
984
|
-
* // ...
|
|
985
|
-
* }
|
|
986
|
-
* }
|
|
987
|
-
* ```
|
|
988
|
-
*/
|
|
989
|
-
function Cooldown(duration, options) {
|
|
990
|
-
let delay;
|
|
991
|
-
if (typeof duration === "number") delay = duration * 1e3;
|
|
992
|
-
else {
|
|
993
|
-
const parsed = (0, _seedcord_utils.parseDuration)(duration);
|
|
994
|
-
if (parsed === null) throw new _seedcord_errors_internal.SeedcordTypeError(_seedcord_errors.SeedcordErrorCode.GateInvalidCooldownDuration, [duration]);
|
|
995
|
-
delay = parsed;
|
|
996
|
-
}
|
|
997
|
-
const bucket = `cooldown:${bucketSeq++}`;
|
|
998
|
-
const per = options?.per ?? "user";
|
|
999
|
-
const window = options?.limit === void 0 ? { delay } : {
|
|
1000
|
-
delay,
|
|
1001
|
-
limit: options.limit
|
|
1002
|
-
};
|
|
1003
|
-
const keyOf = (ctx) => `${bucket}:${scopeValue(ctx, per)}`;
|
|
1004
|
-
return defineEffectGate("Cooldown", (ctx) => {
|
|
1005
|
-
const result = ctx.core.rateLimiter.peek(keyOf(ctx), window);
|
|
1006
|
-
if (!result.limited) return;
|
|
1007
|
-
if (options?.notice) throw options.notice(result.expires);
|
|
1008
|
-
throw new OnCooldown(result.expires, options?.message?.(result.expires));
|
|
1009
|
-
}, (ctx) => {
|
|
1010
|
-
ctx.core.rateLimiter.hit(keyOf(ctx), window);
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
//#endregion
|
|
1015
|
-
//#region src/bot/gates/catalog/IgnoreBots.ts
|
|
1016
|
-
/**
|
|
1017
|
-
* Drops a client event whose actor is a bot, with a {@link Silence} so nothing is replied. Event-only, because a
|
|
1018
|
-
* Silence on an interaction would leave Discord's failed-interaction state. It rejects an interaction handler at
|
|
1019
|
-
* the decorator line. Takes no options, so attach it directly without calling it.
|
|
1020
|
-
*
|
|
1021
|
-
* @see {@link Gated}
|
|
1022
|
-
*
|
|
1023
|
-
* @example
|
|
1024
|
-
* ```ts
|
|
1025
|
-
* import { Events } from 'discord.js';
|
|
1026
|
-
*
|
|
1027
|
-
* \@Gated(IgnoreBots)
|
|
1028
|
-
* class OnMessage extends EventHandler<Events.MessageCreate> {
|
|
1029
|
-
* async execute() {
|
|
1030
|
-
* // ...
|
|
1031
|
-
* }
|
|
1032
|
-
* }
|
|
1033
|
-
* ```
|
|
1034
|
-
*/
|
|
1035
|
-
const IgnoreBots = defineGate("IgnoreBots", (ctx) => {
|
|
1036
|
-
if (ctx.user?.bot) throw new _seedcord_core.Silence("actor is a bot");
|
|
1037
|
-
});
|
|
1038
|
-
|
|
1039
508
|
//#endregion
|
|
1040
509
|
//#region src/bot/gates/catalog/Nsfw.ts
|
|
1041
510
|
function channelIsNsfw(channel) {
|
|
@@ -1064,9 +533,9 @@ function channelIsNsfw(channel) {
|
|
|
1064
533
|
* ```
|
|
1065
534
|
*/
|
|
1066
535
|
function Nsfw(options) {
|
|
1067
|
-
return defineGate("Nsfw", (ctx) => {
|
|
536
|
+
return (0, _seedcord_core.defineGate)("Nsfw", (ctx) => {
|
|
1068
537
|
if (channelIsNsfw(ctx.interaction.channel)) return;
|
|
1069
|
-
throw pickNotice(options, (message) => new NotNsfw(message));
|
|
538
|
+
throw (0, _seedcord_core_internal.pickNotice)(options, (message) => new NotNsfw(message));
|
|
1070
539
|
});
|
|
1071
540
|
}
|
|
1072
541
|
|
|
@@ -1100,6 +569,7 @@ function checkPermissions(a, b, c, d, e) {
|
|
|
1100
569
|
|
|
1101
570
|
//#endregion
|
|
1102
571
|
//#region src/bot/gates/catalog/permissions.ts
|
|
572
|
+
const UNCACHED_MEMBER = "Your server member data could not be resolved. Try again.";
|
|
1103
573
|
/**
|
|
1104
574
|
* Requires the caller to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1105
575
|
*
|
|
@@ -1124,15 +594,16 @@ function checkPermissions(a, b, c, d, e) {
|
|
|
1124
594
|
* ```
|
|
1125
595
|
*/
|
|
1126
596
|
function RequirePermissions(scope, options) {
|
|
1127
|
-
return defineGate("RequirePermissions", (ctx) => {
|
|
1128
|
-
if (!ctx.
|
|
597
|
+
return (0, _seedcord_core.defineGate)("RequirePermissions", (ctx) => {
|
|
598
|
+
if (!ctx.guild) throw (0, _seedcord_core_internal.pickNotice)(options?.notInGuild, (message) => new _seedcord_core_internal.NotInGuild(message));
|
|
599
|
+
if (!ctx.member) throw (0, _seedcord_core_internal.pickNotice)(options?.notInGuild, (message) => new _seedcord_core_internal.NotInGuild(message ?? UNCACHED_MEMBER));
|
|
1129
600
|
checkPermissions(ctx.member, ctx.guild, scope, false, options?.missing ? { missing: options.missing } : void 0);
|
|
1130
601
|
});
|
|
1131
602
|
}
|
|
1132
603
|
/**
|
|
1133
604
|
* Requires the bot to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1134
605
|
*
|
|
1135
|
-
*
|
|
606
|
+
* It reads the bot's own member, so it attaches to modal handlers as well.
|
|
1136
607
|
*
|
|
1137
608
|
* @param scope - The permission flag bits the bot must all hold.
|
|
1138
609
|
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
|
|
@@ -1153,9 +624,9 @@ function RequirePermissions(scope, options) {
|
|
|
1153
624
|
* ```
|
|
1154
625
|
*/
|
|
1155
626
|
function RequireBotPermissions(scope, options) {
|
|
1156
|
-
return defineGate("RequireBotPermissions", (ctx) => {
|
|
627
|
+
return (0, _seedcord_core.defineGate)("RequireBotPermissions", (ctx) => {
|
|
1157
628
|
const botMember = ctx.guild?.members.me;
|
|
1158
|
-
if (!ctx.guild || !botMember) throw pickNotice(options?.notInGuild, (message) => new NotInGuild(message));
|
|
629
|
+
if (!ctx.guild || !botMember) throw (0, _seedcord_core_internal.pickNotice)(options?.notInGuild, (message) => new _seedcord_core_internal.NotInGuild(message));
|
|
1159
630
|
checkPermissions(botMember, ctx.guild, scope, false, options?.missing ? { missing: options.missing } : void 0);
|
|
1160
631
|
});
|
|
1161
632
|
}
|
|
@@ -1182,11 +653,12 @@ function RequireBotPermissions(scope, options) {
|
|
|
1182
653
|
* ```
|
|
1183
654
|
*/
|
|
1184
655
|
function RequireRole(roleId, options) {
|
|
1185
|
-
return defineGate("RequireRole", (ctx) => {
|
|
1186
|
-
if (!ctx.
|
|
656
|
+
return (0, _seedcord_core.defineGate)("RequireRole", (ctx) => {
|
|
657
|
+
if (!ctx.guild) throw (0, _seedcord_core_internal.pickNotice)(options?.notInGuild, (message) => new _seedcord_core_internal.NotInGuild(message));
|
|
658
|
+
if (!ctx.member) throw (0, _seedcord_core_internal.pickNotice)(options?.notInGuild, (message) => new _seedcord_core_internal.NotInGuild(message ?? UNCACHED_MEMBER));
|
|
1187
659
|
if (ctx.member.roles.cache.has(roleId)) return;
|
|
1188
660
|
const role = ctx.guild.roles.cache.get(roleId) ?? null;
|
|
1189
|
-
throw pickNotice(options?.missingRole, (message) => new MissingRole(message, role));
|
|
661
|
+
throw (0, _seedcord_core_internal.pickNotice)(options?.missingRole, (message) => new MissingRole(message, role));
|
|
1190
662
|
});
|
|
1191
663
|
}
|
|
1192
664
|
|
|
@@ -2691,7 +2163,7 @@ function Subscribe(subscriber, options) {
|
|
|
2691
2163
|
subscriber,
|
|
2692
2164
|
frequency: options?.frequency
|
|
2693
2165
|
};
|
|
2694
|
-
Reflect.defineMetadata(SubscribeMetadataKey, meta, constructor);
|
|
2166
|
+
Reflect.defineMetadata(_seedcord_core_internal.SubscribeMetadataKey, meta, constructor);
|
|
2695
2167
|
};
|
|
2696
2168
|
}
|
|
2697
2169
|
|
|
@@ -3003,10 +2475,10 @@ var CommandRegistry = class {
|
|
|
3003
2475
|
}
|
|
3004
2476
|
isCommandClass(obj) {
|
|
3005
2477
|
if (typeof obj !== "function") return false;
|
|
3006
|
-
return obj.prototype instanceof _seedcord_core.BuilderComponent && Reflect.hasMetadata(CommandMetadataKey, obj);
|
|
2478
|
+
return obj.prototype instanceof _seedcord_core.BuilderComponent && Reflect.hasMetadata(_seedcord_core_internal.CommandMetadataKey, obj);
|
|
3007
2479
|
}
|
|
3008
2480
|
registerCommand(ctor, rel) {
|
|
3009
|
-
const meta = Reflect.getMetadata(CommandMetadataKey, ctor);
|
|
2481
|
+
const meta = Reflect.getMetadata(_seedcord_core_internal.CommandMetadataKey, ctor);
|
|
3010
2482
|
if (!meta) return;
|
|
3011
2483
|
const comp = new ctor().component;
|
|
3012
2484
|
const commandType = comp instanceof _discordjs_builders.SlashCommandBuilder ? "slash command" : "context menu command";
|
|
@@ -3082,6 +2554,75 @@ var CommandRegistry = class {
|
|
|
3082
2554
|
}
|
|
3083
2555
|
};
|
|
3084
2556
|
|
|
2557
|
+
//#endregion
|
|
2558
|
+
//#region src/miscellaneous/deriveEventActor.ts
|
|
2559
|
+
function deriveEventActor(args) {
|
|
2560
|
+
const tuple = Array.isArray(args) ? args : [args];
|
|
2561
|
+
for (const arg of tuple) {
|
|
2562
|
+
if (arg instanceof discord_js.Message) return {
|
|
2563
|
+
guild: arg.guild,
|
|
2564
|
+
member: arg.member,
|
|
2565
|
+
user: arg.author,
|
|
2566
|
+
channelId: arg.channelId
|
|
2567
|
+
};
|
|
2568
|
+
if (arg instanceof discord_js.GuildMember) return {
|
|
2569
|
+
guild: arg.guild,
|
|
2570
|
+
member: arg,
|
|
2571
|
+
user: arg.user,
|
|
2572
|
+
channelId: null
|
|
2573
|
+
};
|
|
2574
|
+
if (arg instanceof discord_js.User) return {
|
|
2575
|
+
guild: null,
|
|
2576
|
+
member: null,
|
|
2577
|
+
user: arg,
|
|
2578
|
+
channelId: null
|
|
2579
|
+
};
|
|
2580
|
+
}
|
|
2581
|
+
return {
|
|
2582
|
+
guild: null,
|
|
2583
|
+
member: null,
|
|
2584
|
+
user: null,
|
|
2585
|
+
channelId: null
|
|
2586
|
+
};
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
//#endregion
|
|
2590
|
+
//#region src/bot/gates/runGates.ts
|
|
2591
|
+
function interactionGateContext(interaction, core) {
|
|
2592
|
+
const rawMember = interaction.member;
|
|
2593
|
+
const memberRoleIds = rawMember instanceof discord_js.GuildMember ? [...rawMember.roles.cache.keys()].filter((id) => id !== interaction.guildId) : rawMember?.roles ?? [];
|
|
2594
|
+
return {
|
|
2595
|
+
kind: "interaction",
|
|
2596
|
+
interaction,
|
|
2597
|
+
core,
|
|
2598
|
+
user: interaction.user,
|
|
2599
|
+
guild: interaction.guild,
|
|
2600
|
+
member: rawMember instanceof discord_js.GuildMember ? rawMember : null,
|
|
2601
|
+
userId: interaction.user.id,
|
|
2602
|
+
guildId: interaction.guildId,
|
|
2603
|
+
channelId: interaction.channelId,
|
|
2604
|
+
memberRoleIds,
|
|
2605
|
+
memberPermissions: interaction.memberPermissions?.bitfield ?? null
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
function eventGateContext(eventName, args, core) {
|
|
2609
|
+
const actor = deriveEventActor(args);
|
|
2610
|
+
return {
|
|
2611
|
+
kind: "event",
|
|
2612
|
+
core,
|
|
2613
|
+
eventName,
|
|
2614
|
+
payload: args,
|
|
2615
|
+
user: actor.user,
|
|
2616
|
+
guild: actor.guild,
|
|
2617
|
+
member: actor.member,
|
|
2618
|
+
userId: actor.user?.id ?? null,
|
|
2619
|
+
guildId: actor.guild?.id ?? null,
|
|
2620
|
+
channelId: actor.channelId,
|
|
2621
|
+
memberRoleIds: actor.member ? [...actor.member.roles.cache.keys()].filter((id) => id !== actor.guild?.id) : [],
|
|
2622
|
+
memberPermissions: actor.member?.permissions.bitfield ?? null
|
|
2623
|
+
};
|
|
2624
|
+
}
|
|
2625
|
+
|
|
3085
2626
|
//#endregion
|
|
3086
2627
|
//#region src/miscellaneous/FaultThrottle.ts
|
|
3087
2628
|
/**
|
|
@@ -3391,7 +2932,7 @@ var EventDispatcher = class {
|
|
|
3391
2932
|
if (index !== -1) this.middlewares.splice(index, 1);
|
|
3392
2933
|
}
|
|
3393
2934
|
registerMiddleware(middlewareCtor, relativePath) {
|
|
3394
|
-
const metadata = Reflect.getMetadata(MiddlewareMetadataKey, middlewareCtor);
|
|
2935
|
+
const metadata = Reflect.getMetadata(_seedcord_core_internal.MiddlewareMetadataKey, middlewareCtor);
|
|
3395
2936
|
if (metadata?.type !== "event") return;
|
|
3396
2937
|
if (this.middlewares.some((entry) => entry.ctor === middlewareCtor)) return;
|
|
3397
2938
|
this.middlewares.push({
|
|
@@ -3416,14 +2957,14 @@ var EventDispatcher = class {
|
|
|
3416
2957
|
}
|
|
3417
2958
|
isEventHandlerClass(obj) {
|
|
3418
2959
|
if (typeof obj !== "function") return false;
|
|
3419
|
-
return obj.prototype instanceof EventHandler && Reflect.hasMetadata(EventMetadataKey, obj);
|
|
2960
|
+
return obj.prototype instanceof EventHandler && Reflect.hasMetadata(_seedcord_core_internal.EventMetadataKey, obj);
|
|
3420
2961
|
}
|
|
3421
2962
|
isMiddlewareClass(obj) {
|
|
3422
2963
|
if (typeof obj !== "function") return false;
|
|
3423
|
-
return obj.prototype instanceof EventMiddleware && Reflect.hasMetadata(MiddlewareMetadataKey, obj);
|
|
2964
|
+
return obj.prototype instanceof EventMiddleware && Reflect.hasMetadata(_seedcord_core_internal.MiddlewareMetadataKey, obj);
|
|
3424
2965
|
}
|
|
3425
2966
|
registerHandler(handlerClass, relativePath) {
|
|
3426
|
-
const raw = Reflect.getMetadata(EventMetadataKey, handlerClass);
|
|
2967
|
+
const raw = Reflect.getMetadata(_seedcord_core_internal.EventMetadataKey, handlerClass);
|
|
3427
2968
|
const register = (key, frequency) => {
|
|
3428
2969
|
let handlers = this.eventMap.get(key);
|
|
3429
2970
|
if (!handlers) {
|
|
@@ -3479,7 +3020,7 @@ var EventDispatcher = class {
|
|
|
3479
3020
|
try {
|
|
3480
3021
|
this.logger.debug(`Processing ${chalk.default.bold.green(eventName)} with ${chalk.default.gray(ctor.name)}`);
|
|
3481
3022
|
const handler = new ctor(args, this.core, eventName);
|
|
3482
|
-
await runHandlerGates(ctor, eventGateContext(eventName, args, this.core));
|
|
3023
|
+
await (0, _seedcord_core_internal.runHandlerGates)(ctor, eventGateContext(eventName, args, this.core));
|
|
3483
3024
|
await handler.execute();
|
|
3484
3025
|
} catch (caught) {
|
|
3485
3026
|
handleEventFault(caught, String(eventName), ctor.name, args, this.core);
|
|
@@ -3571,17 +3112,17 @@ var InteractionDispatcher = class {
|
|
|
3571
3112
|
middlewares = [];
|
|
3572
3113
|
hmrHandler;
|
|
3573
3114
|
routeTypes = [
|
|
3574
|
-
[
|
|
3575
|
-
[
|
|
3576
|
-
[
|
|
3577
|
-
[
|
|
3578
|
-
[
|
|
3579
|
-
[
|
|
3580
|
-
[
|
|
3581
|
-
[
|
|
3582
|
-
[
|
|
3583
|
-
[
|
|
3584
|
-
[
|
|
3115
|
+
[_seedcord_core_internal.InteractionRoutes.Slash, this.slashMap],
|
|
3116
|
+
[_seedcord_core_internal.InteractionRoutes.Button, this.buttonMap],
|
|
3117
|
+
[_seedcord_core_internal.InteractionRoutes.Modal, this.modalMap],
|
|
3118
|
+
[_seedcord_core_internal.InteractionRoutes.StringMenu, this.stringSelectMap],
|
|
3119
|
+
[_seedcord_core_internal.InteractionRoutes.UserMenu, this.userSelectMap],
|
|
3120
|
+
[_seedcord_core_internal.InteractionRoutes.RoleMenu, this.roleSelectMap],
|
|
3121
|
+
[_seedcord_core_internal.InteractionRoutes.ChannelMenu, this.channelSelectMap],
|
|
3122
|
+
[_seedcord_core_internal.InteractionRoutes.MentionableMenu, this.mentionableSelectMap],
|
|
3123
|
+
[_seedcord_core_internal.InteractionRoutes.MessageContextMenu, this.messageContextMenuMap],
|
|
3124
|
+
[_seedcord_core_internal.InteractionRoutes.UserContextMenu, this.userContextMenuMap],
|
|
3125
|
+
[_seedcord_core_internal.InteractionRoutes.Autocomplete, this.autocompleteMap]
|
|
3585
3126
|
];
|
|
3586
3127
|
constructor(core) {
|
|
3587
3128
|
this.core = core;
|
|
@@ -3626,7 +3167,7 @@ var InteractionDispatcher = class {
|
|
|
3626
3167
|
getArtifacts(handlerClass) {
|
|
3627
3168
|
const artifacts = [];
|
|
3628
3169
|
for (const [routeType] of this.routeTypes) {
|
|
3629
|
-
const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
|
|
3170
|
+
const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
|
|
3630
3171
|
if (areRoutes(meta)) artifacts.push({
|
|
3631
3172
|
routeType,
|
|
3632
3173
|
routes: meta
|
|
@@ -3682,7 +3223,7 @@ var InteractionDispatcher = class {
|
|
|
3682
3223
|
}, this.logger);
|
|
3683
3224
|
}
|
|
3684
3225
|
registerMiddleware(middlewareCtor, relativePath) {
|
|
3685
|
-
const metadata = Reflect.getMetadata(MiddlewareMetadataKey, middlewareCtor);
|
|
3226
|
+
const metadata = Reflect.getMetadata(_seedcord_core_internal.MiddlewareMetadataKey, middlewareCtor);
|
|
3686
3227
|
if (metadata?.type !== "interaction") return;
|
|
3687
3228
|
if (this.middlewares.some((entry) => entry.ctor === middlewareCtor)) return;
|
|
3688
3229
|
if (this.middlewares.some((entry) => entry.ctor.name === middlewareCtor.name)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.InteractionDuplicateMiddleware, [middlewareCtor.name]);
|
|
@@ -3695,16 +3236,16 @@ var InteractionDispatcher = class {
|
|
|
3695
3236
|
}
|
|
3696
3237
|
isHandlerClass(obj) {
|
|
3697
3238
|
if (typeof obj !== "function") return false;
|
|
3698
|
-
return obj.prototype instanceof InteractionHandler && Reflect.hasMetadata(InteractionMetadataKey, obj) || obj.prototype instanceof AutocompleteHandler && Reflect.hasMetadata(InteractionMetadataKey, obj);
|
|
3239
|
+
return obj.prototype instanceof InteractionHandler && Reflect.hasMetadata(_seedcord_core_internal.InteractionMetadataKey, obj) || obj.prototype instanceof AutocompleteHandler && Reflect.hasMetadata(_seedcord_core_internal.InteractionMetadataKey, obj);
|
|
3699
3240
|
}
|
|
3700
3241
|
isMiddlewareClass(obj) {
|
|
3701
3242
|
if (typeof obj !== "function") return false;
|
|
3702
|
-
return obj.prototype instanceof InteractionMiddleware && Reflect.hasMetadata(MiddlewareMetadataKey, obj);
|
|
3243
|
+
return obj.prototype instanceof InteractionMiddleware && Reflect.hasMetadata(_seedcord_core_internal.MiddlewareMetadataKey, obj);
|
|
3703
3244
|
}
|
|
3704
3245
|
registerHandler(handlerClass, relativePath) {
|
|
3705
3246
|
const writes = [];
|
|
3706
3247
|
for (const [routeType, map] of this.routeTypes) {
|
|
3707
|
-
const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
|
|
3248
|
+
const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
|
|
3708
3249
|
if (!areRoutes(meta)) continue;
|
|
3709
3250
|
for (const route of meta) {
|
|
3710
3251
|
const existing = map.get(route);
|
|
@@ -3732,7 +3273,7 @@ var InteractionDispatcher = class {
|
|
|
3732
3273
|
return;
|
|
3733
3274
|
}
|
|
3734
3275
|
for (const [routeType, map] of this.routeTypes) {
|
|
3735
|
-
const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
|
|
3276
|
+
const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
|
|
3736
3277
|
if (!areRoutes(meta)) continue;
|
|
3737
3278
|
meta.forEach((route) => map.delete(route));
|
|
3738
3279
|
}
|
|
@@ -3767,7 +3308,7 @@ var InteractionDispatcher = class {
|
|
|
3767
3308
|
}
|
|
3768
3309
|
this.logger.debug(`Processing ${chalk.default.bold.green(key)} with ${chalk.default.gray(HandlerCtor.name)}`);
|
|
3769
3310
|
const handler = new HandlerCtor(interaction, this.core);
|
|
3770
|
-
if (!interaction.isAutocomplete()) await runHandlerGates(HandlerCtor, interactionGateContext(interaction, this.core));
|
|
3311
|
+
if (!interaction.isAutocomplete()) await (0, _seedcord_core_internal.runHandlerGates)(HandlerCtor, interactionGateContext(interaction, this.core));
|
|
3771
3312
|
await handler.execute();
|
|
3772
3313
|
} catch (caught) {
|
|
3773
3314
|
await handleInteractionFault(caught, interaction, this.core);
|
|
@@ -4197,7 +3738,7 @@ var Bus = class extends Plugin {
|
|
|
4197
3738
|
}
|
|
4198
3739
|
}
|
|
4199
3740
|
getArtifacts(ctor) {
|
|
4200
|
-
return [Reflect.getMetadata(SubscribeMetadataKey, ctor).subscriber];
|
|
3741
|
+
return [Reflect.getMetadata(_seedcord_core_internal.SubscribeMetadataKey, ctor).subscriber];
|
|
4201
3742
|
}
|
|
4202
3743
|
/** @internal */
|
|
4203
3744
|
async init() {
|
|
@@ -4231,7 +3772,7 @@ var Bus = class extends Plugin {
|
|
|
4231
3772
|
}, this.logger);
|
|
4232
3773
|
}
|
|
4233
3774
|
registerSubscriber(handler) {
|
|
4234
|
-
const options = Reflect.getMetadata(SubscribeMetadataKey, handler);
|
|
3775
|
+
const options = Reflect.getMetadata(_seedcord_core_internal.SubscribeMetadataKey, handler);
|
|
4235
3776
|
let handlers = this.subscribersMap.get(options.subscriber);
|
|
4236
3777
|
if (!handlers) {
|
|
4237
3778
|
handlers = [];
|
|
@@ -4253,7 +3794,7 @@ var Bus = class extends Plugin {
|
|
|
4253
3794
|
}
|
|
4254
3795
|
isSubscriber(obj) {
|
|
4255
3796
|
if (typeof obj !== "function") return false;
|
|
4256
|
-
return obj.prototype instanceof Subscriber && Reflect.hasMetadata(SubscribeMetadataKey, obj);
|
|
3797
|
+
return obj.prototype instanceof Subscriber && Reflect.hasMetadata(_seedcord_core_internal.SubscribeMetadataKey, obj);
|
|
4257
3798
|
}
|
|
4258
3799
|
/**
|
|
4259
3800
|
* Publishes an event to its subscribers and native listeners.
|
|
@@ -4287,6 +3828,11 @@ var Bus = class extends Plugin {
|
|
|
4287
3828
|
}
|
|
4288
3829
|
};
|
|
4289
3830
|
|
|
3831
|
+
//#endregion
|
|
3832
|
+
//#region src/version.ts
|
|
3833
|
+
/** Package version */
|
|
3834
|
+
const version = "0.16.0-next.4";
|
|
3835
|
+
|
|
4290
3836
|
//#endregion
|
|
4291
3837
|
//#region src/Seedcord.ts
|
|
4292
3838
|
/**
|
|
@@ -4303,6 +3849,8 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
4303
3849
|
* @internal
|
|
4304
3850
|
* */
|
|
4305
3851
|
[_seedcord_types_internal.SeedcordBrand] = true;
|
|
3852
|
+
/** The framework package version this instance runs on. */
|
|
3853
|
+
version = version;
|
|
4306
3854
|
static isInstantiated = false;
|
|
4307
3855
|
/** @see {@link CoordinatedShutdown} */
|
|
4308
3856
|
shutdown;
|
|
@@ -4312,7 +3860,7 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
4312
3860
|
bus;
|
|
4313
3861
|
/** @see {@link Bot} */
|
|
4314
3862
|
bot;
|
|
4315
|
-
/** @see {@link
|
|
3863
|
+
/** @see {@link IRateLimiter} */
|
|
4316
3864
|
rateLimiter;
|
|
4317
3865
|
/** @see {@link HealthCheck} */
|
|
4318
3866
|
healthCheck;
|
|
@@ -4338,14 +3886,11 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
4338
3886
|
this.hmrManager.init();
|
|
4339
3887
|
this.bus = new Bus(this);
|
|
4340
3888
|
this.bot = new Bot(this);
|
|
4341
|
-
this.rateLimiter = new
|
|
3889
|
+
this.rateLimiter = new _seedcord_rate_limiter.MemoryRateLimiter();
|
|
4342
3890
|
this.healthCheck = new _seedcord_services.HealthCheck(this.shutdown, config.healthCheck);
|
|
4343
3891
|
this.registerStartupTasks();
|
|
4344
3892
|
}
|
|
4345
|
-
/**
|
|
4346
|
-
* Resets the singleton state.
|
|
4347
|
-
* @internal
|
|
4348
|
-
*/
|
|
3893
|
+
/** @internal */
|
|
4349
3894
|
static reset() {
|
|
4350
3895
|
Seedcord.isInstantiated = false;
|
|
4351
3896
|
}
|
|
@@ -4390,11 +3935,6 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
4390
3935
|
}
|
|
4391
3936
|
};
|
|
4392
3937
|
|
|
4393
|
-
//#endregion
|
|
4394
|
-
//#region src/index.ts
|
|
4395
|
-
/** Package version */
|
|
4396
|
-
const version = "0.16.0-next.3";
|
|
4397
|
-
|
|
4398
3938
|
//#endregion
|
|
4399
3939
|
exports.ArraySource = ArraySource;
|
|
4400
3940
|
exports.AutocompleteHandler = AutocompleteHandler;
|
|
@@ -4404,14 +3944,11 @@ exports.ButtonRoute = ButtonRoute;
|
|
|
4404
3944
|
exports.CommandMentions = CommandMentions;
|
|
4405
3945
|
exports.ContextMenuHandler = ContextMenuHandler;
|
|
4406
3946
|
exports.ContextMenuRoute = ContextMenuRoute;
|
|
4407
|
-
exports.Cooldown = Cooldown;
|
|
4408
3947
|
exports.CursorSource = CursorSource;
|
|
4409
|
-
exports.DmOnly = DmOnly;
|
|
4410
3948
|
exports.Emojis = Emojis;
|
|
4411
3949
|
exports.EventHandler = EventHandler;
|
|
4412
3950
|
exports.EventMiddleware = EventMiddleware;
|
|
4413
3951
|
exports.Gated = Gated;
|
|
4414
|
-
exports.GuildOnly = GuildOnly;
|
|
4415
3952
|
exports.HmrModuleHandler = HmrModuleHandler;
|
|
4416
3953
|
exports.IgnoreBots = IgnoreBots;
|
|
4417
3954
|
exports.InteractionHandler = InteractionHandler;
|
|
@@ -4421,11 +3958,15 @@ exports.MiddlewareType = MiddlewareType;
|
|
|
4421
3958
|
exports.ModalHandler = ModalHandler;
|
|
4422
3959
|
exports.ModalRoute = ModalRoute;
|
|
4423
3960
|
exports.Nsfw = Nsfw;
|
|
4424
|
-
exports.OwnerOnly = OwnerOnly;
|
|
4425
3961
|
exports.Paginator = Paginator;
|
|
4426
3962
|
exports.Pluggable = Pluggable;
|
|
4427
3963
|
exports.Plugin = Plugin;
|
|
4428
|
-
exports
|
|
3964
|
+
Object.defineProperty(exports, 'RegisterCommand', {
|
|
3965
|
+
enumerable: true,
|
|
3966
|
+
get: function () {
|
|
3967
|
+
return _seedcord_core.RegisterCommand;
|
|
3968
|
+
}
|
|
3969
|
+
});
|
|
4429
3970
|
exports.RegisterEvent = RegisterEvent;
|
|
4430
3971
|
exports.ReplySender = ReplySender;
|
|
4431
3972
|
exports.RequireBotPermissions = RequireBotPermissions;
|
|
@@ -4440,11 +3981,8 @@ exports.SlashRoute = SlashRoute;
|
|
|
4440
3981
|
exports.Subscribe = Subscribe;
|
|
4441
3982
|
exports.Subscriber = Subscriber;
|
|
4442
3983
|
exports.WebhookLog = WebhookLog;
|
|
4443
|
-
exports.and = and;
|
|
4444
3984
|
exports.checkBotPermissions = checkBotPermissions;
|
|
4445
3985
|
exports.checkPermissions = checkPermissions;
|
|
4446
|
-
exports.defineEffectGate = defineEffectGate;
|
|
4447
|
-
exports.defineGate = defineGate;
|
|
4448
3986
|
exports.fetchGuildMember = fetchGuildMember;
|
|
4449
3987
|
exports.fetchManyGuildMembers = fetchManyGuildMembers;
|
|
4450
3988
|
exports.fetchManyUsers = fetchManyUsers;
|
|
@@ -4454,7 +3992,6 @@ exports.fetchUser = fetchUser;
|
|
|
4454
3992
|
exports.getBotRole = getBotRole;
|
|
4455
3993
|
exports.getConfirmation = getConfirmation;
|
|
4456
3994
|
exports.hasPermsToAssign = hasPermsToAssign;
|
|
4457
|
-
exports.or = or;
|
|
4458
3995
|
exports.updateMemberRoles = updateMemberRoles;
|
|
4459
3996
|
exports.version = version;
|
|
4460
3997
|
Object.keys(_seedcord_core).forEach(function (k) {
|
|
@@ -4471,6 +4008,13 @@ Object.keys(_seedcord_errors).forEach(function (k) {
|
|
|
4471
4008
|
});
|
|
4472
4009
|
});
|
|
4473
4010
|
|
|
4011
|
+
Object.keys(_seedcord_rate_limiter).forEach(function (k) {
|
|
4012
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
4013
|
+
enumerable: true,
|
|
4014
|
+
get: function () { return _seedcord_rate_limiter[k]; }
|
|
4015
|
+
});
|
|
4016
|
+
});
|
|
4017
|
+
|
|
4474
4018
|
Object.keys(_seedcord_services).forEach(function (k) {
|
|
4475
4019
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
4476
4020
|
enumerable: true,
|