seedcord 0.16.0-next.2 → 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 CHANGED
@@ -27,73 +27,26 @@ 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_kit_internal = require("@seedcord/kit/internal");
34
- let _seedcord_kit = require("@seedcord/kit");
35
35
  let _seedcord_utils = require("@seedcord/utils");
36
36
  let _seedcord_services = require("@seedcord/services");
37
37
  let chalk = require("chalk");
38
38
  chalk = __toESM(chalk, 1);
39
+ let _discordjs_builders = require("@discordjs/builders");
39
40
  let _seedcord_utils_internal = require("@seedcord/utils/internal");
40
41
  let node_fs = require("node:fs");
41
42
  let node_path = require("node:path");
42
43
  let node_url = require("node:url");
44
+ let _seedcord_rate_limiter = require("@seedcord/rate-limiter");
43
45
  let _seedcord_types_internal = require("@seedcord/types/internal");
44
46
  let envapt = require("envapt");
45
47
  let node_crypto = require("node:crypto");
46
48
  node_crypto = __toESM(node_crypto, 1);
47
49
 
48
- //#region src/metadataKeys.ts
49
- /** @internal */
50
- const InteractionMetadataKey = Symbol("seedcord:interaction:metadata");
51
- /** @internal */
52
- const InteractionRouteKeys = {
53
- ["slash"]: Symbol("seedcord:interaction:slash"),
54
- ["button"]: Symbol("seedcord:interaction:button"),
55
- ["modal"]: Symbol("seedcord:interaction:modal"),
56
- ["stringMenu"]: Symbol("seedcord:interaction:stringMenu"),
57
- ["userMenu"]: Symbol("seedcord:interaction:userMenu"),
58
- ["roleMenu"]: Symbol("seedcord:interaction:roleMenu"),
59
- ["channelMenu"]: Symbol("seedcord:interaction:channelMenu"),
60
- ["mentionableMenu"]: Symbol("seedcord:interaction:mentionableMenu"),
61
- ["messageContextMenu"]: Symbol("seedcord:interaction:messageContextMenu"),
62
- ["userContextMenu"]: Symbol("seedcord:interaction:userContextMenu"),
63
- ["autocomplete"]: Symbol("seedcord:interaction:autocomplete")
64
- };
65
- /** @internal */
66
- const MiddlewareMetadataKey = Symbol("seedcord:middleware:metadata");
67
- /** @internal */
68
- const EventMetadataKey = Symbol("seedcord:event:metadata");
69
- /** @internal */
70
- const CommandMetadataKey = Symbol("seedcord:command:metadata");
71
- /** @internal */
72
- const GatedMetadataKey = Symbol("seedcord:gated:metadata");
73
- /** @internal */
74
- const SubscribeMetadataKey = Symbol("seedcord:subscribe:metadata");
75
-
76
- //#endregion
77
- //#region src/bot/decorators/Command.ts
78
- function RegisterCommand(scope, guilds = []) {
79
- return (ctor) => {
80
- const meta = scope === "global" ? { scope } : {
81
- scope,
82
- guilds
83
- };
84
- const existingMeta = Reflect.getOwnMetadata(CommandMetadataKey, ctor);
85
- if (existingMeta) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandAlreadyRegistered, [
86
- ctor.name,
87
- existingMeta.scope,
88
- scope
89
- ]);
90
- if (scope === "global" && guilds.length > 0) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandGlobalWithGuilds);
91
- if (scope === "guild" && (!Array.isArray(guilds) || guilds.length === 0)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.DecoratorCommandGuildWithoutGuilds);
92
- Reflect.defineMetadata(CommandMetadataKey, meta, ctor);
93
- };
94
- }
95
-
96
- //#endregion
97
50
  //#region src/bot/decorators/Events.ts
98
51
  /**
99
52
  * Registers an event handler class with one or more Discord.js events.
@@ -137,126 +90,12 @@ function RegisterCommand(scope, guilds = []) {
137
90
  */
138
91
  function RegisterEvent(...defs) {
139
92
  return function(constructor) {
140
- const existing = Reflect.getMetadata(EventMetadataKey, constructor) ?? [];
93
+ const existing = Reflect.getMetadata(_seedcord_core_internal.EventMetadataKey, constructor) ?? [];
141
94
  const entries = defs.map(([event, options]) => ({
142
95
  event,
143
96
  frequency: options?.frequency ?? "on"
144
97
  }));
145
- Reflect.defineMetadata(EventMetadataKey, [...existing, ...entries], constructor);
146
- };
147
- }
148
-
149
- //#endregion
150
- //#region src/miscellaneous/deriveEventActor.ts
151
- function deriveEventActor(args) {
152
- const tuple = Array.isArray(args) ? args : [args];
153
- for (const arg of tuple) {
154
- if (arg instanceof discord_js.Message) return {
155
- guild: arg.guild,
156
- member: arg.member,
157
- user: arg.author,
158
- channelId: arg.channelId
159
- };
160
- if (arg instanceof discord_js.GuildMember) return {
161
- guild: arg.guild,
162
- member: arg,
163
- user: arg.user,
164
- channelId: null
165
- };
166
- if (arg instanceof discord_js.User) return {
167
- guild: null,
168
- member: null,
169
- user: arg,
170
- channelId: null
171
- };
172
- }
173
- return {
174
- guild: null,
175
- member: null,
176
- user: null,
177
- channelId: null
178
- };
179
- }
180
-
181
- //#endregion
182
- //#region src/bot/gates/effects.ts
183
- const commitQueues = /* @__PURE__ */ new WeakMap();
184
- function isEffectGate(gate) {
185
- return typeof gate.check === "function" && typeof gate.commit === "function";
186
- }
187
- /**
188
- * Runs a gate's check and, when it passes and carries an effect, queues its commit against the context. A
189
- * refusal throws here before the queue, so a refused effect gate never commits. The combinators and the
190
- * runner both go through this, so an effect gate inside `and`/`or` queues the same way a top-level one does.
191
- */
192
- async function runCheck(gate, ctx) {
193
- await gate.check(ctx);
194
- if (!isEffectGate(gate)) return;
195
- let queue = commitQueues.get(ctx);
196
- if (!queue) {
197
- queue = [];
198
- commitQueues.set(ctx, queue);
199
- }
200
- queue.push(() => gate.commit(ctx));
201
- }
202
- /** Drains the queued commits once the whole set has passed. */
203
- async function runCommits(ctx) {
204
- const queue = commitQueues.get(ctx);
205
- if (!queue) return;
206
- for (const commit of queue) await commit();
207
- }
208
- /** Drops a context's queue. The runner calls this after every run, so a refused or drained run leaves no stale queue behind. */
209
- function discardCommits(ctx) {
210
- commitQueues.delete(ctx);
211
- }
212
- /** The current queued-commit count, a mark an `or` arm rolls back to if it refuses. */
213
- function markCommits(ctx) {
214
- return commitQueues.get(ctx)?.length ?? 0;
215
- }
216
- /** Drops commits queued after `mark`, so an `or` arm that queued an effect then refused leaves nothing for the winning arm to carry. */
217
- function rollbackCommits(ctx, mark) {
218
- const queue = commitQueues.get(ctx);
219
- if (queue && queue.length > mark) queue.length = mark;
220
- }
221
-
222
- //#endregion
223
- //#region src/bot/gates/runGates.ts
224
- /**
225
- * Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect
226
- * gate's commit runs once the whole set passes.
227
- */
228
- async function runGates(gates, ctx) {
229
- try {
230
- for (const gate of gates) await runCheck(gate, ctx);
231
- await runCommits(ctx);
232
- } finally {
233
- discardCommits(ctx);
234
- }
235
- }
236
- function interactionGateContext(interaction, core) {
237
- return {
238
- kind: "interaction",
239
- interaction,
240
- core,
241
- user: interaction.user,
242
- guild: interaction.guild,
243
- member: interaction.member instanceof discord_js.GuildMember ? interaction.member : null,
244
- guildId: interaction.guildId,
245
- channelId: interaction.channelId
246
- };
247
- }
248
- function eventGateContext(eventName, args, core) {
249
- const actor = deriveEventActor(args);
250
- return {
251
- kind: "event",
252
- core,
253
- eventName,
254
- payload: args,
255
- user: actor.user,
256
- guild: actor.guild,
257
- member: actor.member,
258
- guildId: actor.guild?.id ?? null,
259
- channelId: actor.channelId
98
+ Reflect.defineMetadata(_seedcord_core_internal.EventMetadataKey, [...existing, ...entries], constructor);
260
99
  };
261
100
  }
262
101
 
@@ -295,22 +134,10 @@ function eventGateContext(eventName, args, core) {
295
134
  */
296
135
  function Gated(...gates) {
297
136
  return function(ctor) {
298
- const existing = Reflect.getMetadata(GatedMetadataKey, ctor) ?? [];
299
- 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);
300
139
  };
301
140
  }
302
- /**
303
- * Runs the gates a handler was decorated with against the given context. The dispatcher calls this before
304
- * `execute`, inside the boundary, so a refusal renders or drops.
305
- *
306
- * @param handlerCtor - The handler class whose attached gates are read from metadata.
307
- * @param ctx - The context passed to each gate, supplying what the gate checks against.
308
- */
309
- async function runHandlerGates(handlerCtor, ctx) {
310
- const gates = Reflect.getMetadata(GatedMetadataKey, handlerCtor);
311
- if (!gates) return;
312
- await runGates(gates, ctx);
313
- }
314
141
 
315
142
  //#endregion
316
143
  //#region src/miscellaneous/areRoutes.ts
@@ -367,7 +194,7 @@ let SelectMenuKind = /* @__PURE__ */ function(SelectMenuKind) {
367
194
  */
368
195
  function SlashRoute(...routes) {
369
196
  return function(constructor) {
370
- storeMetadata("slash", routes, constructor);
197
+ storeMetadata(_seedcord_core_internal.InteractionRoutes.Slash, routes, constructor);
371
198
  };
372
199
  }
373
200
  /**
@@ -383,7 +210,7 @@ function SlashRoute(...routes) {
383
210
  */
384
211
  function ButtonRoute(...defs) {
385
212
  return function(constructor) {
386
- storeComponentRoute("button", defs, constructor);
213
+ storeComponentRoute(_seedcord_core_internal.InteractionRoutes.Button, defs, constructor);
387
214
  };
388
215
  }
389
216
  /**
@@ -399,7 +226,7 @@ function ButtonRoute(...defs) {
399
226
  */
400
227
  function ModalRoute(...defs) {
401
228
  return function(constructor) {
402
- storeComponentRoute("modal", defs, constructor);
229
+ storeComponentRoute(_seedcord_core_internal.InteractionRoutes.Modal, defs, constructor);
403
230
  };
404
231
  }
405
232
  /**
@@ -425,7 +252,7 @@ function ModalRoute(...defs) {
425
252
  */
426
253
  function ContextMenuRoute(kind, ...names) {
427
254
  return function(constructor) {
428
- storeMetadata(kind === discord_js.ApplicationCommandType.User ? "userContextMenu" : "messageContextMenu", names, constructor);
255
+ storeMetadata(kind === discord_js.ApplicationCommandType.User ? _seedcord_core_internal.InteractionRoutes.UserContextMenu : _seedcord_core_internal.InteractionRoutes.MessageContextMenu, names, constructor);
429
256
  };
430
257
  }
431
258
  /**
@@ -450,7 +277,7 @@ function ContextMenuRoute(kind, ...names) {
450
277
  */
451
278
  function AutocompleteRoute(...routes) {
452
279
  return function(constructor) {
453
- storeMetadata("autocomplete", routes, constructor);
280
+ storeMetadata(_seedcord_core_internal.InteractionRoutes.Autocomplete, routes, constructor);
454
281
  };
455
282
  }
456
283
  /**
@@ -475,25 +302,25 @@ function AutocompleteRoute(...routes) {
475
302
  function SelectMenuRoute(type, ...defs) {
476
303
  return function(constructor) {
477
304
  storeComponentRoute({
478
- ["string"]: "stringMenu",
479
- ["user"]: "userMenu",
480
- ["role"]: "roleMenu",
481
- ["channel"]: "channelMenu",
482
- ["mentionable"]: "mentionableMenu"
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
483
310
  }[type], defs, constructor);
484
311
  };
485
312
  }
486
313
  function storeComponentRoute(route, defs, constructor) {
487
314
  storeMetadata(route, defs.map((def) => def.prefix), constructor);
488
- Reflect.defineMetadata(_seedcord_kit_internal.ComponentDefsKey, defs, constructor);
315
+ Reflect.defineMetadata(_seedcord_core_internal.ComponentDefsKey, defs, constructor);
489
316
  }
490
317
  function storeMetadata(route, routes, constructor) {
491
- const key = InteractionRouteKeys[route];
318
+ const key = _seedcord_core_internal.InteractionRouteKeys[route];
492
319
  const savedRoutes = Reflect.getMetadata(key, constructor);
493
320
  const existing = areRoutes(savedRoutes) ? savedRoutes : [];
494
321
  const toStore = Array.isArray(routes) ? routes : [routes];
495
322
  Reflect.defineMetadata(key, [...existing, ...toStore], constructor);
496
- Reflect.defineMetadata(InteractionMetadataKey, true, constructor);
323
+ Reflect.defineMetadata(_seedcord_core_internal.InteractionMetadataKey, true, constructor);
497
324
  }
498
325
 
499
326
  //#endregion
@@ -535,111 +362,34 @@ function Middleware(type, priority = 0, options = {}) {
535
362
  type,
536
363
  ...options.events && options.events.length > 0 && { events: options.events }
537
364
  };
538
- Reflect.defineMetadata(MiddlewareMetadataKey, metadata, ctor);
365
+ Reflect.defineMetadata(_seedcord_core_internal.MiddlewareMetadataKey, metadata, ctor);
539
366
  };
540
367
  }
541
368
 
542
369
  //#endregion
543
- //#region src/bot/gates/Gate.ts
370
+ //#region src/bot/gates/catalog/IgnoreBots.ts
544
371
  /**
545
- * Builds a {@link Gate} from a check. The check refuses by throwing a Notice or a Silence and passes
546
- * by returning. The required context is inferred from `ctx`, so annotate it as narrowly as the fields
547
- * the check reads. No annotation defaults to {@link GateContextBase}, an agnostic gate that fits every
548
- * handler.
549
- *
550
- * @typeParam Name - The gate's name captured as a literal, so a mismatch error can name the gate.
551
- * @typeParam Ctx - The context the check reads, inferred from the `ctx` annotation.
552
- *
553
- * @param name - The gate's name, used in mismatch errors.
554
- * @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.
555
375
  *
556
- * @see {@link defineEffectGate}
557
376
  * @see {@link Gated}
558
377
  *
559
378
  * @example
560
379
  * ```ts
561
- * // a gate factory that takes its own option and closes over it
562
- * function MinRoleCount(min: number): Gate<InteractionGateContext, 'MinRoleCount'> {
563
- * return defineGate('MinRoleCount', (ctx: InteractionGateContext) => {
564
- * if (ctx.member && ctx.member.roles.cache.size < min) throw new NotEnoughRoles(min);
565
- * });
566
- * }
567
- * ```
568
- *
569
- * @example
570
- * ```ts
571
- * // agnostic gate (no ctx annotation): fits any handler
572
- * const Owner = defineGate('owner', (ctx) => {
573
- * if (!ctx.user) throw new NotOwner();
574
- * });
575
- * ```
576
- *
577
- * @example
578
- * ```ts
579
- * // interaction-only gate: annotate ctx to narrow the required context
580
- * const SlashGate = defineGate('slash', (ctx: InteractionGateContext) => {
581
- * void ctx.interaction;
582
- * });
583
- * ```
584
- *
585
- * @example
586
- * ```ts
587
380
  * import { Events } from 'discord.js';
588
381
  *
589
- * // event-only gate keyed to one event
590
- * const OnMessage = defineGate('msg', (ctx: EventGateContext<Events.MessageCreate>) => {
591
- * void ctx.payload;
592
- * });
593
- * ```
594
- */
595
- function defineGate(name, fn) {
596
- return {
597
- name,
598
- check: async (ctx) => fn(ctx)
599
- };
600
- }
601
- /**
602
- * Builds an {@link EffectGate} from a `check` and a `commit`. `check` peeks and refuses by throwing, and
603
- * `commit` applies the side effect, running only once the whole gate set passes so a later refusal never
604
- * commits. In an `or`, a refusing arm's queued commit is rolled back. This is how {@link Cooldown} peeks
605
- * in `check` and charges the slot in `commit`.
606
- *
607
- * @typeParam Name - The gate's name captured as a literal, so a mismatch error can name the gate.
608
- * @typeParam Ctx - The context both `check` and `commit` read, inferred from the `ctx` annotation.
609
- *
610
- * @param name - The gate's name, used in mismatch errors.
611
- * @param check - Peeks and refuses by throwing, without applying the side effect.
612
- * @param commit - Applies the side effect, running only after the whole gate set passes.
613
- *
614
- * @see {@link defineGate}
615
- * @see {@link Gated}
616
- * @see {@link Cooldown}
617
- *
618
- * @example
619
- * ```ts
620
- * // an effect-gate factory that takes its own limit and closes over it
621
- * function UsesPerDay(max: number): EffectGate<GateContextBase, 'UsesPerDay'> {
622
- * return defineEffectGate(
623
- * 'UsesPerDay',
624
- * (ctx) => {
625
- * // peek and refuse by throwing, do not mutate yet
626
- * if (usedToday(ctx.user) >= max) throw new OutOfUsesNotice(max);
627
- * },
628
- * (ctx) => {
629
- * // runs only after the whole gate set passes
630
- * recordUse(ctx.user);
631
- * }
632
- * );
382
+ * \@Gated(IgnoreBots)
383
+ * class OnMessage extends EventHandler<Events.MessageCreate> {
384
+ * async execute() {
385
+ * // ...
386
+ * }
633
387
  * }
634
388
  * ```
635
389
  */
636
- function defineEffectGate(name, check, commit) {
637
- return {
638
- name,
639
- check: async (ctx) => check(ctx),
640
- commit: async (ctx) => commit(ctx)
641
- };
642
- }
390
+ const IgnoreBots = (0, _seedcord_core.defineGate)("IgnoreBots", (ctx) => {
391
+ if (ctx.user?.bot) throw new _seedcord_core.Silence("actor is a bot");
392
+ });
643
393
 
644
394
  //#endregion
645
395
  //#region src/bot/notices/utils.ts
@@ -658,64 +408,19 @@ function labelFor(subject) {
658
408
 
659
409
  //#endregion
660
410
  //#region src/bot/notices/index.ts
661
- var GateNotice = class extends _seedcord_kit.Notice {
662
- render() {
663
- return { components: [new _seedcord_kit_internal.NoticeCard(this.message).component] };
664
- }
665
- };
666
- var NotOwner = class extends GateNotice {
667
- constructor(message = "Only the bot owner can use this.") {
668
- super(message);
669
- }
670
- };
671
- var NotInGuild = class extends GateNotice {
672
- constructor(message = "This can only be used in a server.") {
673
- super(message);
674
- }
675
- };
676
- var NotInDm = class extends GateNotice {
677
- constructor(message = "This can only be used in a direct message.") {
678
- super(message);
679
- }
680
- };
681
- var NotNsfw = class extends GateNotice {
411
+ var NotNsfw = class extends _seedcord_core_internal.GateNotice {
682
412
  constructor(message = "This can only be used in an age-restricted channel.") {
683
413
  super(message);
684
414
  }
685
415
  };
686
- var OnCooldown = class extends GateNotice {
687
- expires;
688
- constructor(expires, message) {
689
- super(message ?? `You are doing that too fast. Try again <t:${(0, _seedcord_utils.toEpochSeconds)(expires)}:R>.`);
690
- this.expires = expires;
691
- }
692
- };
693
- var MissingRole = class extends GateNotice {
416
+ var MissingRole = class extends _seedcord_core_internal.GateNotice {
694
417
  role;
695
418
  constructor(message, role) {
696
419
  super(message ?? (role ? `You need the ${role.name} role to use this.` : "You do not have the required role."));
697
420
  this.role = role;
698
421
  }
699
422
  };
700
- var NotAllowed = class extends _seedcord_kit.Notice {
701
- constructor() {
702
- super("not allowed");
703
- }
704
- render() {
705
- return { components: [new _seedcord_kit_internal.NoticeCard("You are not allowed to use this command.").component] };
706
- }
707
- };
708
- var NeedsAny = class extends _seedcord_kit.Notice {
709
- summaries;
710
- constructor(summaries) {
711
- super("not allowed");
712
- this.summaries = summaries;
713
- }
714
- render() {
715
- return { components: [new _seedcord_kit_internal.NoticeCard(`You need any of:\n${this.summaries.map((summary) => `• ${summary}`).join("\n")}`).component] };
716
- }
717
- };
718
- var RoleHigherThanMe = class extends _seedcord_kit.Notice {
423
+ var RoleHigherThanMe = class extends _seedcord_core.Notice {
719
424
  role;
720
425
  botRole;
721
426
  constructor(message, role, botRole) {
@@ -724,18 +429,18 @@ var RoleHigherThanMe = class extends _seedcord_kit.Notice {
724
429
  this.botRole = botRole;
725
430
  }
726
431
  render() {
727
- return { components: [new _seedcord_kit_internal.NoticeCard(`I cannot assign a role that is higher than me.\n\nThe role <@&${this.role.id}> is higher than my role <@&${this.botRole.id}> in the hierarchy.`).component] };
432
+ return { components: [new _seedcord_core_internal.NoticeCard(`I cannot assign a role that is higher than me.\n\nThe role <@&${this.role.id}> is higher than my role <@&${this.botRole.id}> in the hierarchy.`).component] };
728
433
  }
729
434
  };
730
- var CannotAssignBotRole = class extends _seedcord_kit.Notice {
435
+ var CannotAssignBotRole = class extends _seedcord_core.Notice {
731
436
  constructor(message = "I cannot assign a managed role.") {
732
437
  super(message);
733
438
  }
734
439
  render() {
735
- return { components: [new _seedcord_kit_internal.NoticeCard("I cannot assign a managed role.").component] };
440
+ return { components: [new _seedcord_core_internal.NoticeCard("I cannot assign a managed role.").component] };
736
441
  }
737
442
  };
738
- var MissingPermissions = class extends _seedcord_kit.Notice {
443
+ var MissingPermissions = class extends _seedcord_core.Notice {
739
444
  where;
740
445
  missingPerms;
741
446
  constructor(message, where, missingPerms) {
@@ -745,10 +450,10 @@ var MissingPermissions = class extends _seedcord_kit.Notice {
745
450
  }
746
451
  render() {
747
452
  const bullets = this.missingPerms.map((perm) => `• ${perm}`).join("\n");
748
- return { components: [new _seedcord_kit_internal.NoticeCard(`The ${labelFor(this.where)} ${mentionFor(this.where)} is missing the following permission entries:\n\n${bullets}`).component] };
453
+ return { components: [new _seedcord_core_internal.NoticeCard(`The ${labelFor(this.where)} ${mentionFor(this.where)} is missing the following permission entries:\n\n${bullets}`).component] };
749
454
  }
750
455
  };
751
- var HasDangerousPermissions = class extends _seedcord_kit.Notice {
456
+ var HasDangerousPermissions = class extends _seedcord_core.Notice {
752
457
  target;
753
458
  dangerousPerms;
754
459
  constructor(message, target, dangerousPerms) {
@@ -758,283 +463,48 @@ var HasDangerousPermissions = class extends _seedcord_kit.Notice {
758
463
  }
759
464
  render() {
760
465
  const bullets = this.dangerousPerms.map((perm) => `• ${perm}`).join("\n");
761
- return { components: [new _seedcord_kit_internal.NoticeCard(`The ${labelFor(this.target)} ${mentionFor(this.target)} has the following permission entries that must not be enabled:\n\n${bullets}`).component] };
466
+ return { components: [new _seedcord_core_internal.NoticeCard(`The ${labelFor(this.target)} ${mentionFor(this.target)} has the following permission entries that must not be enabled:\n\n${bullets}`).component] };
762
467
  }
763
468
  };
764
- var UserNotFound = class extends _seedcord_kit.Notice {
469
+ var UserNotFound = class extends _seedcord_core.Notice {
765
470
  userArg;
766
471
  constructor(userArg) {
767
472
  super(`User not found: ${userArg}`);
768
473
  this.userArg = userArg;
769
474
  }
770
475
  render() {
771
- return { components: [new _seedcord_kit_internal.NoticeCard(`User probably doesn't exist or was deleted.\n**User Argument:** \`${this.userArg}\`\nPlease check the user ID and try again. Only pass valid user IDs as the argument.`, "User Not Found").component] };
476
+ return { components: [new _seedcord_core_internal.NoticeCard(`User probably doesn't exist or was deleted.\n**User Argument:** \`${this.userArg}\`\nPlease check the user ID and try again. Only pass valid user IDs as the argument.`, "User Not Found").component] };
772
477
  }
773
478
  };
774
- var UserNotInGuild = class extends _seedcord_kit.Notice {
479
+ var UserNotInGuild = class extends _seedcord_core.Notice {
775
480
  constructor(message = "User is not in the guild.") {
776
481
  super(message);
777
482
  }
778
483
  render() {
779
- return { components: [new _seedcord_kit_internal.NoticeCard(this.message).component] };
484
+ return { components: [new _seedcord_core_internal.NoticeCard(this.message).component] };
780
485
  }
781
486
  };
782
- var RoleDoesNotExist = class extends _seedcord_kit.Notice {
487
+ var RoleDoesNotExist = class extends _seedcord_core.Notice {
783
488
  roleId;
784
489
  constructor(message, roleId) {
785
490
  super(message);
786
491
  this.roleId = roleId;
787
492
  }
788
493
  render() {
789
- return { components: [new _seedcord_kit_internal.NoticeCard(`The role with ID \`${this.roleId}\` does not exist.`).component] };
494
+ return { components: [new _seedcord_core_internal.NoticeCard(`The role with ID \`${this.roleId}\` does not exist.`).component] };
790
495
  }
791
496
  };
792
- var CouldNotFindChannel = class extends _seedcord_kit.Notice {
497
+ var CouldNotFindChannel = class extends _seedcord_core.Notice {
793
498
  channelId;
794
499
  constructor(message, channelId) {
795
500
  super(message);
796
501
  this.channelId = channelId;
797
502
  }
798
503
  render() {
799
- return { components: [new _seedcord_kit_internal.NoticeCard(`Could not find channel with ID \`${this.channelId}\`. It could also be that the channel is not a text channel.`).component] };
504
+ return { components: [new _seedcord_core_internal.NoticeCard(`Could not find channel with ID \`${this.channelId}\`. It could also be that the channel is not a text channel.`).component] };
800
505
  }
801
506
  };
802
507
 
803
- //#endregion
804
- //#region src/bot/gates/combinators.ts
805
- function and(...gates) {
806
- return defineGate("and", async (ctx) => {
807
- for (const gate of gates) await runCheck(gate, ctx);
808
- });
809
- }
810
- function isOrOptions(arg) {
811
- return !("check" in arg);
812
- }
813
- function or(...args) {
814
- const last = args.at(-1);
815
- const options = last !== void 0 && isOrOptions(last) ? last : void 0;
816
- const gates = options ? args.slice(0, -1) : args;
817
- return defineGate("or", async (ctx) => {
818
- const summaries = [];
819
- let everyArmHasSummary = true;
820
- for (const gate of gates) {
821
- const mark = markCommits(ctx);
822
- try {
823
- await runCheck(gate, ctx);
824
- return;
825
- } catch (error) {
826
- if (error instanceof _seedcord_kit.Notice && !error.report) {
827
- rollbackCommits(ctx, mark);
828
- if (error.summary === void 0) everyArmHasSummary = false;
829
- else summaries.push(error.summary);
830
- continue;
831
- }
832
- throw error;
833
- }
834
- }
835
- if (options) throw typeof options.fail === "function" ? options.fail(ctx) : options.fail;
836
- if (everyArmHasSummary && summaries.length > 0) throw new NeedsAny(summaries);
837
- throw new NotAllowed();
838
- });
839
- }
840
-
841
- //#endregion
842
- //#region src/bot/gates/catalog/options.ts
843
- function pickNotice(options, makeDefault) {
844
- return options?.notice ?? makeDefault(options?.message);
845
- }
846
-
847
- //#endregion
848
- //#region src/bot/gates/catalog/access.ts
849
- /**
850
- * Passes only for a user id listed in `config.ownerIds`, else refuses.
851
- *
852
- * 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.
853
- *
854
- * @param options - Reword the default refusal with `message`, or replace it with `notice`.
855
- *
856
- * @see {@link Gated}
857
- *
858
- * @example
859
- * ```ts
860
- * \@Gated(OwnerOnly())
861
- * \@SlashRoute('shutdown')
862
- * class ShutdownHandler extends SlashHandler<'shutdown'> {
863
- * async execute() {
864
- * // ...
865
- * }
866
- * }
867
- * ```
868
- *
869
- * @example
870
- * ```ts
871
- * // reword the refusal, keeping the embed styling
872
- * OwnerOnly({ message: 'Owners only.' });
873
- * ```
874
- */
875
- function OwnerOnly(options) {
876
- return defineGate("OwnerOnly", (ctx) => {
877
- const owners = ctx.core.config.ownerIds ?? [];
878
- if (ctx.user && owners.includes(ctx.user.id)) return;
879
- throw pickNotice(options, (message) => new NotOwner(message));
880
- });
881
- }
882
- /**
883
- * Passes inside a guild, else refuses.
884
- *
885
- * Agnostic, so it attaches to any handler kind. Often paired with {@link RequirePermissions} in an {@link and}.
886
- *
887
- * @param options - Reword the default refusal with `message`, or replace it with `notice`.
888
- *
889
- * @see {@link Gated}
890
- *
891
- * @example
892
- * ```ts
893
- * import { PermissionFlagsBits } from 'discord.js';
894
- *
895
- * \@Gated(GuildOnly(), RequirePermissions([PermissionFlagsBits.Administrator]))
896
- * \@SlashRoute('maintenance')
897
- * class Maintenance extends SlashHandler<'maintenance'> {
898
- * async execute() {
899
- * // ...
900
- * }
901
- * }
902
- * ```
903
- */
904
- function GuildOnly(options) {
905
- return defineGate("GuildOnly", (ctx) => {
906
- if (ctx.guild) return;
907
- throw pickNotice(options, (message) => new NotInGuild(message));
908
- });
909
- }
910
- /**
911
- * Passes in a direct message, else refuses.
912
- *
913
- * Agnostic, so it attaches to any handler kind. The inverse of {@link GuildOnly}, so combining the two in an {@link and} can never pass.
914
- *
915
- * @param options - Reword the default refusal with `message`, or replace it with `notice`.
916
- *
917
- * @see {@link Gated}
918
- *
919
- * @example
920
- * ```ts
921
- * \@Gated(DmOnly())
922
- * \@SlashRoute('verify')
923
- * class VerifyHandler extends SlashHandler<'verify'> {
924
- * async execute() {
925
- * // ...
926
- * }
927
- * }
928
- * ```
929
- */
930
- function DmOnly(options) {
931
- return defineGate("DmOnly", (ctx) => {
932
- if (!ctx.guild) return;
933
- throw pickNotice(options, (message) => new NotInDm(message));
934
- });
935
- }
936
-
937
- //#endregion
938
- //#region src/bot/gates/catalog/Cooldown.ts
939
- let bucketSeq = 0;
940
- function scopeValue(ctx, per) {
941
- if (per === "guild") return ctx.guildId ?? "global";
942
- if (per === "channel") return ctx.channelId ?? "global";
943
- return ctx.user?.id ?? "global";
944
- }
945
- /**
946
- * Allows `limit` uses per window, scoped by `per`. A number `duration` is **seconds**, a string is
947
- * a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError** at construction. The
948
- * slot is charged in commit, only after the whole gate set passes, so a later refusal never burns the cooldown.
949
- * Each call gets its own bucket, so two handlers never share a window. Reword the refusal with {@link CooldownOptions.message}
950
- * or replace it with {@link CooldownOptions.notice}.
951
- *
952
- * @param duration - A number is seconds, a string is a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError**.
953
- * @param options - Sets the scope with `per`, the uses per window with `limit`, and the refusal text with `message` or `notice`.
954
- *
955
- * @see {@link Gated}
956
- * @see {@link RateLimiter}
957
- *
958
- * @example
959
- * ```ts
960
- * // a number argument is SECONDS
961
- * \@Gated(Cooldown(5))
962
- * \@SlashRoute('daily')
963
- * class DailyHandler extends SlashHandler<'daily'> {
964
- * async execute() {
965
- * // ...
966
- * }
967
- * }
968
- * ```
969
- *
970
- * @example
971
- * ```ts
972
- * // a string is a duration, here scoped per guild instead of per user
973
- * Cooldown('30m', { per: 'guild' });
974
- * ```
975
- *
976
- * @example
977
- * ```ts
978
- * // a burst, 3 uses per 10 minutes per user, then it refuses until a slot frees
979
- * \@Gated(Cooldown('10m', { limit: 3 }))
980
- * \@SlashRoute('report')
981
- * class ReportHandler extends SlashHandler<'report'> {
982
- * async execute() {
983
- * // ...
984
- * }
985
- * }
986
- * ```
987
- */
988
- function Cooldown(duration, options) {
989
- let delay;
990
- if (typeof duration === "number") delay = duration * 1e3;
991
- else {
992
- const parsed = (0, _seedcord_utils.parseDuration)(duration);
993
- if (parsed === null) throw new _seedcord_errors_internal.SeedcordTypeError(_seedcord_errors.SeedcordErrorCode.GateInvalidCooldownDuration, [duration]);
994
- delay = parsed;
995
- }
996
- const bucket = `cooldown:${bucketSeq++}`;
997
- const per = options?.per ?? "user";
998
- const window = options?.limit === void 0 ? { delay } : {
999
- delay,
1000
- limit: options.limit
1001
- };
1002
- const keyOf = (ctx) => `${bucket}:${scopeValue(ctx, per)}`;
1003
- return defineEffectGate("Cooldown", (ctx) => {
1004
- const result = ctx.core.rateLimiter.peek(keyOf(ctx), window);
1005
- if (!result.limited) return;
1006
- if (options?.notice) throw options.notice(result.expires);
1007
- throw new OnCooldown(result.expires, options?.message?.(result.expires));
1008
- }, (ctx) => {
1009
- ctx.core.rateLimiter.hit(keyOf(ctx), window);
1010
- });
1011
- }
1012
-
1013
- //#endregion
1014
- //#region src/bot/gates/catalog/IgnoreBots.ts
1015
- /**
1016
- * Drops a client event whose actor is a bot, with a {@link Silence} so nothing is replied. Event-only, because a
1017
- * Silence on an interaction would leave Discord's failed-interaction state. It rejects an interaction handler at
1018
- * the decorator line. Takes no options, so attach it directly without calling it.
1019
- *
1020
- * @see {@link Gated}
1021
- *
1022
- * @example
1023
- * ```ts
1024
- * import { Events } from 'discord.js';
1025
- *
1026
- * \@Gated(IgnoreBots)
1027
- * class OnMessage extends EventHandler<Events.MessageCreate> {
1028
- * async execute() {
1029
- * // ...
1030
- * }
1031
- * }
1032
- * ```
1033
- */
1034
- const IgnoreBots = defineGate("IgnoreBots", (ctx) => {
1035
- if (ctx.user?.bot) throw new _seedcord_kit.Silence("actor is a bot");
1036
- });
1037
-
1038
508
  //#endregion
1039
509
  //#region src/bot/gates/catalog/Nsfw.ts
1040
510
  function channelIsNsfw(channel) {
@@ -1063,9 +533,9 @@ function channelIsNsfw(channel) {
1063
533
  * ```
1064
534
  */
1065
535
  function Nsfw(options) {
1066
- return defineGate("Nsfw", (ctx) => {
536
+ return (0, _seedcord_core.defineGate)("Nsfw", (ctx) => {
1067
537
  if (channelIsNsfw(ctx.interaction.channel)) return;
1068
- throw pickNotice(options, (message) => new NotNsfw(message));
538
+ throw (0, _seedcord_core_internal.pickNotice)(options, (message) => new NotNsfw(message));
1069
539
  });
1070
540
  }
1071
541
 
@@ -1099,6 +569,7 @@ function checkPermissions(a, b, c, d, e) {
1099
569
 
1100
570
  //#endregion
1101
571
  //#region src/bot/gates/catalog/permissions.ts
572
+ const UNCACHED_MEMBER = "Your server member data could not be resolved. Try again.";
1102
573
  /**
1103
574
  * Requires the caller to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
1104
575
  *
@@ -1123,15 +594,16 @@ function checkPermissions(a, b, c, d, e) {
1123
594
  * ```
1124
595
  */
1125
596
  function RequirePermissions(scope, options) {
1126
- return defineGate("RequirePermissions", (ctx) => {
1127
- if (!ctx.member || !ctx.guild) throw pickNotice(options?.notInGuild, (message) => new NotInGuild(message));
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));
1128
600
  checkPermissions(ctx.member, ctx.guild, scope, false, options?.missing ? { missing: options.missing } : void 0);
1129
601
  });
1130
602
  }
1131
603
  /**
1132
604
  * Requires the bot to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
1133
605
  *
1134
- * Checks the bot's own member, so unlike {@link RequirePermissions} it attaches to a modal handler too.
606
+ * It reads the bot's own member, so it attaches to modal handlers as well.
1135
607
  *
1136
608
  * @param scope - The permission flag bits the bot must all hold.
1137
609
  * @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
@@ -1152,9 +624,9 @@ function RequirePermissions(scope, options) {
1152
624
  * ```
1153
625
  */
1154
626
  function RequireBotPermissions(scope, options) {
1155
- return defineGate("RequireBotPermissions", (ctx) => {
627
+ return (0, _seedcord_core.defineGate)("RequireBotPermissions", (ctx) => {
1156
628
  const botMember = ctx.guild?.members.me;
1157
- 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));
1158
630
  checkPermissions(botMember, ctx.guild, scope, false, options?.missing ? { missing: options.missing } : void 0);
1159
631
  });
1160
632
  }
@@ -1181,11 +653,12 @@ function RequireBotPermissions(scope, options) {
1181
653
  * ```
1182
654
  */
1183
655
  function RequireRole(roleId, options) {
1184
- return defineGate("RequireRole", (ctx) => {
1185
- if (!ctx.member || !ctx.guild) throw pickNotice(options?.notInGuild, (message) => new NotInGuild(message));
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));
1186
659
  if (ctx.member.roles.cache.has(roleId)) return;
1187
660
  const role = ctx.guild.roles.cache.get(roleId) ?? null;
1188
- throw pickNotice(options?.missingRole, (message) => new MissingRole(message, role));
661
+ throw (0, _seedcord_core_internal.pickNotice)(options?.missingRole, (message) => new MissingRole(message, role));
1189
662
  });
1190
663
  }
1191
664
 
@@ -1310,7 +783,7 @@ var CommandMentionInjector = class {
1310
783
  allSlashBuilders() {
1311
784
  const registry = this.core.bot.commands;
1312
785
  if (!registry) return [];
1313
- const slash = [...registry.globalCommands, ...registry.guildCommands.values()].flat().filter((command) => command instanceof discord_js.SlashCommandBuilder);
786
+ const slash = [...registry.globalCommands, ...registry.guildCommands.values()].flat().filter((command) => command instanceof _discordjs_builders.SlashCommandBuilder);
1314
787
  return [...new Set(slash)];
1315
788
  }
1316
789
  indexByName(collection) {
@@ -1715,7 +1188,7 @@ const RESERVED_CONFIRM_PREFIX = "__seedcord_confirm";
1715
1188
  *
1716
1189
  * @internal
1717
1190
  */
1718
- const CONFIRM_DEF = new _seedcord_kit.CustomId(RESERVED_CONFIRM_PREFIX).oneOf("choice", ["confirm", "cancel"]);
1191
+ const CONFIRM_DEF = new _seedcord_core.CustomId(RESERVED_CONFIRM_PREFIX).oneOf("choice", ["confirm", "cancel"]);
1719
1192
 
1720
1193
  //#endregion
1721
1194
  //#region src/bot/confirm/getConfirmation.ts
@@ -1724,16 +1197,16 @@ const CONFIRM_IDS = {
1724
1197
  confirm: CONFIRM_DEF.encode({ choice: "confirm" }),
1725
1198
  cancel: CONFIRM_DEF.encode({ choice: "cancel" })
1726
1199
  };
1727
- var ConfirmButtons = class extends _seedcord_kit.RowComponent {
1200
+ var ConfirmButtons = class extends _seedcord_core.RowComponent {
1728
1201
  constructor(options) {
1729
1202
  super("button");
1730
- this.instance.addComponents(new discord_js.ButtonBuilder().setCustomId(CONFIRM_IDS.confirm).setLabel(options?.confirmLabel ?? "Confirm").setStyle(options?.confirmStyle ?? discord_js.ButtonStyle.Danger), new discord_js.ButtonBuilder().setCustomId(CONFIRM_IDS.cancel).setLabel(options?.cancelLabel ?? "Cancel").setStyle(discord_js.ButtonStyle.Secondary));
1203
+ this.instance.addComponents(new _discordjs_builders.ButtonBuilder().setCustomId(CONFIRM_IDS.confirm).setLabel(options?.confirmLabel ?? "Confirm").setStyle(options?.confirmStyle ?? discord_js.ButtonStyle.Danger), new _discordjs_builders.ButtonBuilder().setCustomId(CONFIRM_IDS.cancel).setLabel(options?.cancelLabel ?? "Cancel").setStyle(discord_js.ButtonStyle.Secondary));
1731
1204
  }
1732
1205
  };
1733
- var ConfirmPromptCard = class extends _seedcord_kit.BuilderComponent {
1206
+ var ConfirmPromptCard = class extends _seedcord_core.BuilderComponent {
1734
1207
  constructor(text, options) {
1735
1208
  super("container");
1736
- this.instance.addTextDisplayComponents(new discord_js.TextDisplayBuilder().setContent(text)).addActionRowComponents(new ConfirmButtons(options).component);
1209
+ this.instance.addTextDisplayComponents(new _discordjs_builders.TextDisplayBuilder().setContent(text)).addActionRowComponents(new ConfirmButtons(options).component);
1737
1210
  }
1738
1211
  };
1739
1212
  function defaultPrompt(text, options) {
@@ -2170,14 +1643,14 @@ var AutocompleteHandler = class extends BaseHandler {
2170
1643
  */
2171
1644
  var ComponentHandler = class extends InteractionHandler {
2172
1645
  get registeredDefs() {
2173
- const defs = Reflect.getMetadata(_seedcord_kit_internal.ComponentDefsKey, this.constructor);
1646
+ const defs = Reflect.getMetadata(_seedcord_core_internal.ComponentDefsKey, this.constructor);
2174
1647
  if (!defs) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CustomIdHandlerRouteMissing, [this.constructor.name]);
2175
1648
  return defs;
2176
1649
  }
2177
1650
  decoded;
2178
1651
  get route() {
2179
1652
  if (this.decoded) return this.decoded;
2180
- const decoded = (0, _seedcord_kit_internal.decodeFor)(this.registeredDefs, this.event.customId);
1653
+ const decoded = (0, _seedcord_core_internal.decodeFor)(this.registeredDefs, this.event.customId);
2181
1654
  this.decoded = decoded;
2182
1655
  return decoded;
2183
1656
  }
@@ -2424,8 +1897,8 @@ var Controls = class {
2424
1897
  const { target, disabled } = this.navState(key);
2425
1898
  const defaultLabel = key === "indicator" ? this.indicatorText() : DEFAULT_LABEL[key];
2426
1899
  const label = cosmetics?.label ?? (key === "indicator" || !cosmetics?.emoji ? defaultLabel : void 0);
2427
- const button = new discord_js.ButtonBuilder().setCustomId(this.cursor.encode({
2428
- page: Math.min(Math.max(0, target), _seedcord_kit_internal.PAGE_MAX),
1900
+ const button = new _discordjs_builders.ButtonBuilder().setCustomId(this.cursor.encode({
1901
+ page: Math.min(Math.max(0, target), _seedcord_core_internal.PAGE_MAX),
2429
1902
  slot: CONTROL_SLOT[key]
2430
1903
  })).setStyle(cosmetics?.style ?? discord_js.ButtonStyle.Secondary).setDisabled(disabled);
2431
1904
  if (label !== void 0) button.setLabel(label);
@@ -2447,8 +1920,8 @@ var Controls = class {
2447
1920
  first: !hasPrev,
2448
1921
  prev: !hasPrev,
2449
1922
  indicator: true,
2450
- next: !hasNext || page + 1 > _seedcord_kit_internal.PAGE_MAX,
2451
- last: !hasNext || !knownTotal || totalPages - 1 > _seedcord_kit_internal.PAGE_MAX
1923
+ next: !hasNext || page + 1 > _seedcord_core_internal.PAGE_MAX,
1924
+ last: !hasNext || !knownTotal || totalPages - 1 > _seedcord_core_internal.PAGE_MAX
2452
1925
  }[key]
2453
1926
  };
2454
1927
  }
@@ -2460,7 +1933,7 @@ var Controls = class {
2460
1933
  if (seen.has(key)) throw new _seedcord_errors_internal.SeedcordTypeError(_seedcord_errors.SeedcordErrorCode.PaginationDuplicateControls, [key]);
2461
1934
  seen.add(key);
2462
1935
  }
2463
- return new discord_js.ActionRowBuilder().addComponents(keys.map((key) => this.button(key)));
1936
+ return new _discordjs_builders.ActionRowBuilder().addComponents(keys.map((key) => this.button(key)));
2464
1937
  }
2465
1938
  indicatorText() {
2466
1939
  const { page, totalPages } = this.view;
@@ -2470,14 +1943,14 @@ var Controls = class {
2470
1943
 
2471
1944
  //#endregion
2472
1945
  //#region src/pagination/render.ts
2473
- var PageContainer = class extends _seedcord_kit.BuilderComponent {
1946
+ var PageContainer = class extends _seedcord_core.BuilderComponent {
2474
1947
  constructor(view, renderItem, controlRow) {
2475
1948
  super("container");
2476
1949
  const base = view.page * view.perPage;
2477
1950
  let lines = [];
2478
1951
  const flush = () => {
2479
1952
  if (lines.length === 0) return;
2480
- this.instance.addTextDisplayComponents(new discord_js.TextDisplayBuilder().setContent(lines.join("\n")));
1953
+ this.instance.addTextDisplayComponents(new _discordjs_builders.TextDisplayBuilder().setContent(lines.join("\n")));
2481
1954
  lines = [];
2482
1955
  };
2483
1956
  view.items.forEach((item, offset) => {
@@ -2494,7 +1967,7 @@ var PageContainer = class extends _seedcord_kit.BuilderComponent {
2494
1967
  }
2495
1968
  };
2496
1969
  function toReplyResponse(renderable) {
2497
- if (typeof renderable === "string") return { components: [new discord_js.TextDisplayBuilder().setContent(renderable)] };
1970
+ if (typeof renderable === "string") return { components: [new _discordjs_builders.TextDisplayBuilder().setContent(renderable)] };
2498
1971
  if (Array.isArray(renderable)) return { components: renderable };
2499
1972
  return renderable;
2500
1973
  }
@@ -2556,7 +2029,7 @@ var Paginator = class {
2556
2029
  Handler;
2557
2030
  config;
2558
2031
  constructor(config) {
2559
- this.cursor = (0, _seedcord_kit_internal.pageCursor)(config.prefix);
2032
+ this.cursor = (0, _seedcord_core_internal.pageCursor)(config.prefix);
2560
2033
  this.config = config;
2561
2034
  const loadPage = (ctx, n) => this.page(ctx, n);
2562
2035
  this.Handler = class Nav extends ButtonHandler {
@@ -2597,7 +2070,7 @@ var ArraySource = class {
2597
2070
  if (!Number.isSafeInteger(this.perPage) || this.perPage <= 0) throw new _seedcord_errors_internal.SeedcordRangeError(_seedcord_errors.SeedcordErrorCode.PaginationInvalidPerPage, [this.perPage]);
2598
2071
  }
2599
2072
  async page(ctx, n) {
2600
- return (0, _seedcord_kit.paginate)(await this.load(ctx), n, this.perPage);
2073
+ return (0, _seedcord_core.paginate)(await this.load(ctx), n, this.perPage);
2601
2074
  }
2602
2075
  };
2603
2076
  /**
@@ -2690,7 +2163,7 @@ function Subscribe(subscriber, options) {
2690
2163
  subscriber,
2691
2164
  frequency: options?.frequency
2692
2165
  };
2693
- Reflect.defineMetadata(SubscribeMetadataKey, meta, constructor);
2166
+ Reflect.defineMetadata(_seedcord_core_internal.SubscribeMetadataKey, meta, constructor);
2694
2167
  };
2695
2168
  }
2696
2169
 
@@ -2889,7 +2362,7 @@ function contextMenuLeaves(commands) {
2889
2362
  const user = /* @__PURE__ */ new Set();
2890
2363
  const message = /* @__PURE__ */ new Set();
2891
2364
  for (const command of commands) {
2892
- if (!(command instanceof discord_js.ContextMenuCommandBuilder)) continue;
2365
+ if (!(command instanceof _discordjs_builders.ContextMenuCommandBuilder)) continue;
2893
2366
  if (command.type === discord_js.ApplicationCommandType.User) user.add(command.name);
2894
2367
  else message.add(command.name);
2895
2368
  }
@@ -2912,7 +2385,7 @@ function contextMenuLeaves(commands) {
2912
2385
  function slashRouteLeaves(commands) {
2913
2386
  const leaves = /* @__PURE__ */ new Set();
2914
2387
  for (const command of commands) {
2915
- if (!(command instanceof discord_js.SlashCommandBuilder)) continue;
2388
+ if (!(command instanceof _discordjs_builders.SlashCommandBuilder)) continue;
2916
2389
  for (const leaf of (0, _seedcord_utils_internal.routeLeavesOf)(command.toJSON())) leaves.add(leaf.route);
2917
2390
  }
2918
2391
  return leaves;
@@ -3002,13 +2475,13 @@ var CommandRegistry = class {
3002
2475
  }
3003
2476
  isCommandClass(obj) {
3004
2477
  if (typeof obj !== "function") return false;
3005
- return obj.prototype instanceof _seedcord_kit.BuilderComponent && Reflect.hasMetadata(CommandMetadataKey, obj);
2478
+ return obj.prototype instanceof _seedcord_core.BuilderComponent && Reflect.hasMetadata(_seedcord_core_internal.CommandMetadataKey, obj);
3006
2479
  }
3007
2480
  registerCommand(ctor, rel) {
3008
- const meta = Reflect.getMetadata(CommandMetadataKey, ctor);
2481
+ const meta = Reflect.getMetadata(_seedcord_core_internal.CommandMetadataKey, ctor);
3009
2482
  if (!meta) return;
3010
2483
  const comp = new ctor().component;
3011
- const commandType = comp instanceof discord_js.SlashCommandBuilder ? "slash command" : "context menu command";
2484
+ const commandType = comp instanceof _discordjs_builders.SlashCommandBuilder ? "slash command" : "context menu command";
3012
2485
  if (meta.scope === "global") {
3013
2486
  this.globalCommands.push(comp);
3014
2487
  this.logger.utils.registration(ctor.name, rel);
@@ -3081,6 +2554,75 @@ var CommandRegistry = class {
3081
2554
  }
3082
2555
  };
3083
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
+
3084
2626
  //#endregion
3085
2627
  //#region src/miscellaneous/FaultThrottle.ts
3086
2628
  /**
@@ -3141,7 +2683,7 @@ function extractErrorResponse(error, core, origin) {
3141
2683
  uuid,
3142
2684
  developerUsername
3143
2685
  };
3144
- if (error instanceof _seedcord_kit.Notice) {
2686
+ if (error instanceof _seedcord_core.Notice) {
3145
2687
  if (error.report) reportFault(error, core, origin, uuid);
3146
2688
  return {
3147
2689
  uuid,
@@ -3152,7 +2694,7 @@ function extractErrorResponse(error, core, origin) {
3152
2694
  const override = core.config.errors?.defaultError;
3153
2695
  return {
3154
2696
  uuid,
3155
- response: override ? new override(uuid).render(ctx) : new _seedcord_kit.Fault().render(ctx)
2697
+ response: override ? new override(uuid).render(ctx) : new _seedcord_core.Fault().render(ctx)
3156
2698
  };
3157
2699
  }
3158
2700
  function withThrottle(origin, error, publish) {
@@ -3219,7 +2761,7 @@ function buildEventSource(event, origin) {
3219
2761
  };
3220
2762
  }
3221
2763
  function faultKey(origin, error) {
3222
- const name = error instanceof _seedcord_kit.Notice ? error.name : error instanceof discord_js.DiscordAPIError ? String(error.code) : error.constructor.name;
2764
+ const name = error instanceof _seedcord_core.Notice ? error.name : error instanceof discord_js.DiscordAPIError ? String(error.code) : error.constructor.name;
3223
2765
  if (origin.event) return `${origin.event.name}:${origin.event.handler}:${name}`;
3224
2766
  if (origin.interaction) return `${interactionRoute(origin.interaction)}:${name}`;
3225
2767
  if (origin.route) return `autocomplete:${origin.route}:${name}`;
@@ -3228,7 +2770,7 @@ function faultKey(origin, error) {
3228
2770
  function interactionRoute(interaction) {
3229
2771
  if (interaction.isChatInputCommand()) return slashRouteOf(interaction);
3230
2772
  if (interaction.isContextMenuCommand()) return interaction.commandName;
3231
- if (interaction.isButton() || interaction.isAnySelectMenu() || interaction.isModalSubmit()) return (0, _seedcord_kit_internal.prefixOf)(interaction.customId) || interaction.customId;
2773
+ if (interaction.isButton() || interaction.isAnySelectMenu() || interaction.isModalSubmit()) return (0, _seedcord_core_internal.prefixOf)(interaction.customId) || interaction.customId;
3232
2774
  return "interaction";
3233
2775
  }
3234
2776
  function buildInteractionSource(interaction) {
@@ -3265,7 +2807,7 @@ const logger$1 = new _seedcord_services.Logger("EventBoundary");
3265
2807
  * @internal
3266
2808
  */
3267
2809
  function handleEventFault(caught, eventName, handlerName, args, core) {
3268
- if (caught instanceof _seedcord_kit.Silence) {
2810
+ if (caught instanceof _seedcord_core.Silence) {
3269
2811
  if (caught.reason !== void 0) logger$1.debug(`Silence: ${caught.reason}`);
3270
2812
  return;
3271
2813
  }
@@ -3275,7 +2817,7 @@ function handleEventFault(caught, eventName, handlerName, args, core) {
3275
2817
  logger$1.debug(`swallowed api code ${caught.code}`);
3276
2818
  return;
3277
2819
  }
3278
- if (caught instanceof _seedcord_kit.Notice && !caught.report) return;
2820
+ if (caught instanceof _seedcord_core.Notice && !caught.report) return;
3279
2821
  const actor = deriveEventActor(args);
3280
2822
  extractErrorResponse(caught, core, {
3281
2823
  event: {
@@ -3303,7 +2845,7 @@ var EventDispatcher = class {
3303
2845
  logger = new _seedcord_services.Logger("Events");
3304
2846
  isInitialized = false;
3305
2847
  name = "Events";
3306
- eventMap = new discord_js.Collection();
2848
+ eventMap = /* @__PURE__ */ new Map();
3307
2849
  middlewares = [];
3308
2850
  executedOnceHandlers = /* @__PURE__ */ new Set();
3309
2851
  attachedEvents = /* @__PURE__ */ new Set();
@@ -3390,7 +2932,7 @@ var EventDispatcher = class {
3390
2932
  if (index !== -1) this.middlewares.splice(index, 1);
3391
2933
  }
3392
2934
  registerMiddleware(middlewareCtor, relativePath) {
3393
- const metadata = Reflect.getMetadata(MiddlewareMetadataKey, middlewareCtor);
2935
+ const metadata = Reflect.getMetadata(_seedcord_core_internal.MiddlewareMetadataKey, middlewareCtor);
3394
2936
  if (metadata?.type !== "event") return;
3395
2937
  if (this.middlewares.some((entry) => entry.ctor === middlewareCtor)) return;
3396
2938
  this.middlewares.push({
@@ -3415,14 +2957,14 @@ var EventDispatcher = class {
3415
2957
  }
3416
2958
  isEventHandlerClass(obj) {
3417
2959
  if (typeof obj !== "function") return false;
3418
- return obj.prototype instanceof EventHandler && Reflect.hasMetadata(EventMetadataKey, obj);
2960
+ return obj.prototype instanceof EventHandler && Reflect.hasMetadata(_seedcord_core_internal.EventMetadataKey, obj);
3419
2961
  }
3420
2962
  isMiddlewareClass(obj) {
3421
2963
  if (typeof obj !== "function") return false;
3422
- return obj.prototype instanceof EventMiddleware && Reflect.hasMetadata(MiddlewareMetadataKey, obj);
2964
+ return obj.prototype instanceof EventMiddleware && Reflect.hasMetadata(_seedcord_core_internal.MiddlewareMetadataKey, obj);
3423
2965
  }
3424
2966
  registerHandler(handlerClass, relativePath) {
3425
- const raw = Reflect.getMetadata(EventMetadataKey, handlerClass);
2967
+ const raw = Reflect.getMetadata(_seedcord_core_internal.EventMetadataKey, handlerClass);
3426
2968
  const register = (key, frequency) => {
3427
2969
  let handlers = this.eventMap.get(key);
3428
2970
  if (!handlers) {
@@ -3478,7 +3020,7 @@ var EventDispatcher = class {
3478
3020
  try {
3479
3021
  this.logger.debug(`Processing ${chalk.default.bold.green(eventName)} with ${chalk.default.gray(ctor.name)}`);
3480
3022
  const handler = new ctor(args, this.core, eventName);
3481
- await runHandlerGates(ctor, eventGateContext(eventName, args, this.core));
3023
+ await (0, _seedcord_core_internal.runHandlerGates)(ctor, eventGateContext(eventName, args, this.core));
3482
3024
  await handler.execute();
3483
3025
  } catch (caught) {
3484
3026
  handleEventFault(caught, String(eventName), ctor.name, args, this.core);
@@ -3514,7 +3056,7 @@ const logger = new _seedcord_services.Logger("InteractionBoundary");
3514
3056
  * @internal
3515
3057
  */
3516
3058
  async function handleInteractionFault(caught, interaction, core) {
3517
- if (caught instanceof _seedcord_kit.Silence) {
3059
+ if (caught instanceof _seedcord_core.Silence) {
3518
3060
  if (caught.reason !== void 0) logger.debug(`Silence: ${caught.reason}`);
3519
3061
  return;
3520
3062
  }
@@ -3539,7 +3081,7 @@ async function handleInteractionFault(caught, interaction, core) {
3539
3081
  user: interaction.user,
3540
3082
  metadata: interaction
3541
3083
  });
3542
- await new ReplySender(interaction).send(response, caught instanceof _seedcord_kit.Notice ? caught.ephemeral : true);
3084
+ await new ReplySender(interaction).send(response, caught instanceof _seedcord_core.Notice ? caught.ephemeral : true);
3543
3085
  }
3544
3086
 
3545
3087
  //#endregion
@@ -3555,32 +3097,32 @@ var InteractionDispatcher = class {
3555
3097
  logger = new _seedcord_services.Logger("Interactions");
3556
3098
  isInitialized = false;
3557
3099
  name = "Interactions";
3558
- slashMap = new discord_js.Collection();
3559
- buttonMap = new discord_js.Collection();
3560
- modalMap = new discord_js.Collection();
3561
- stringSelectMap = new discord_js.Collection();
3562
- userSelectMap = new discord_js.Collection();
3563
- roleSelectMap = new discord_js.Collection();
3564
- channelSelectMap = new discord_js.Collection();
3565
- mentionableSelectMap = new discord_js.Collection();
3566
- messageContextMenuMap = new discord_js.Collection();
3567
- userContextMenuMap = new discord_js.Collection();
3568
- autocompleteMap = new discord_js.Collection();
3100
+ slashMap = /* @__PURE__ */ new Map();
3101
+ buttonMap = /* @__PURE__ */ new Map();
3102
+ modalMap = /* @__PURE__ */ new Map();
3103
+ stringSelectMap = /* @__PURE__ */ new Map();
3104
+ userSelectMap = /* @__PURE__ */ new Map();
3105
+ roleSelectMap = /* @__PURE__ */ new Map();
3106
+ channelSelectMap = /* @__PURE__ */ new Map();
3107
+ mentionableSelectMap = /* @__PURE__ */ new Map();
3108
+ messageContextMenuMap = /* @__PURE__ */ new Map();
3109
+ userContextMenuMap = /* @__PURE__ */ new Map();
3110
+ autocompleteMap = /* @__PURE__ */ new Map();
3569
3111
  keysToIgnore = /* @__PURE__ */ new Set();
3570
3112
  middlewares = [];
3571
3113
  hmrHandler;
3572
3114
  routeTypes = [
3573
- ["slash", this.slashMap],
3574
- ["button", this.buttonMap],
3575
- ["modal", this.modalMap],
3576
- ["stringMenu", this.stringSelectMap],
3577
- ["userMenu", this.userSelectMap],
3578
- ["roleMenu", this.roleSelectMap],
3579
- ["channelMenu", this.channelSelectMap],
3580
- ["mentionableMenu", this.mentionableSelectMap],
3581
- ["messageContextMenu", this.messageContextMenuMap],
3582
- ["userContextMenu", this.userContextMenuMap],
3583
- ["autocomplete", this.autocompleteMap]
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]
3584
3126
  ];
3585
3127
  constructor(core) {
3586
3128
  this.core = core;
@@ -3625,7 +3167,7 @@ var InteractionDispatcher = class {
3625
3167
  getArtifacts(handlerClass) {
3626
3168
  const artifacts = [];
3627
3169
  for (const [routeType] of this.routeTypes) {
3628
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
3170
+ const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
3629
3171
  if (areRoutes(meta)) artifacts.push({
3630
3172
  routeType,
3631
3173
  routes: meta
@@ -3681,7 +3223,7 @@ var InteractionDispatcher = class {
3681
3223
  }, this.logger);
3682
3224
  }
3683
3225
  registerMiddleware(middlewareCtor, relativePath) {
3684
- const metadata = Reflect.getMetadata(MiddlewareMetadataKey, middlewareCtor);
3226
+ const metadata = Reflect.getMetadata(_seedcord_core_internal.MiddlewareMetadataKey, middlewareCtor);
3685
3227
  if (metadata?.type !== "interaction") return;
3686
3228
  if (this.middlewares.some((entry) => entry.ctor === middlewareCtor)) return;
3687
3229
  if (this.middlewares.some((entry) => entry.ctor.name === middlewareCtor.name)) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.InteractionDuplicateMiddleware, [middlewareCtor.name]);
@@ -3694,16 +3236,16 @@ var InteractionDispatcher = class {
3694
3236
  }
3695
3237
  isHandlerClass(obj) {
3696
3238
  if (typeof obj !== "function") return false;
3697
- 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);
3698
3240
  }
3699
3241
  isMiddlewareClass(obj) {
3700
3242
  if (typeof obj !== "function") return false;
3701
- return obj.prototype instanceof InteractionMiddleware && Reflect.hasMetadata(MiddlewareMetadataKey, obj);
3243
+ return obj.prototype instanceof InteractionMiddleware && Reflect.hasMetadata(_seedcord_core_internal.MiddlewareMetadataKey, obj);
3702
3244
  }
3703
3245
  registerHandler(handlerClass, relativePath) {
3704
3246
  const writes = [];
3705
3247
  for (const [routeType, map] of this.routeTypes) {
3706
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
3248
+ const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
3707
3249
  if (!areRoutes(meta)) continue;
3708
3250
  for (const route of meta) {
3709
3251
  const existing = map.get(route);
@@ -3731,7 +3273,7 @@ var InteractionDispatcher = class {
3731
3273
  return;
3732
3274
  }
3733
3275
  for (const [routeType, map] of this.routeTypes) {
3734
- const meta = Reflect.getMetadata(InteractionRouteKeys[routeType], handlerClass);
3276
+ const meta = Reflect.getMetadata(_seedcord_core_internal.InteractionRouteKeys[routeType], handlerClass);
3735
3277
  if (!areRoutes(meta)) continue;
3736
3278
  meta.forEach((route) => map.delete(route));
3737
3279
  }
@@ -3751,7 +3293,7 @@ var InteractionDispatcher = class {
3751
3293
  }
3752
3294
  async handleCustomIdInteraction(interaction, getMap, interactionType) {
3753
3295
  if ([...this.keysToIgnore].some((matcher) => matcher.owns(interaction.customId))) return;
3754
- const prefix = (0, _seedcord_kit_internal.prefixOf)(interaction.customId);
3296
+ const prefix = (0, _seedcord_core_internal.prefixOf)(interaction.customId);
3755
3297
  if (!prefix) return this.logger.warn(`${interactionType} has invalid customId: ${interaction.customId}`);
3756
3298
  await this.processInteraction(interaction, () => prefix, (key) => getMap().get(key));
3757
3299
  }
@@ -3766,7 +3308,7 @@ var InteractionDispatcher = class {
3766
3308
  }
3767
3309
  this.logger.debug(`Processing ${chalk.default.bold.green(key)} with ${chalk.default.gray(HandlerCtor.name)}`);
3768
3310
  const handler = new HandlerCtor(interaction, this.core);
3769
- 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));
3770
3312
  await handler.execute();
3771
3313
  } catch (caught) {
3772
3314
  await handleInteractionFault(caught, interaction, this.core);
@@ -4027,7 +3569,7 @@ function jsonAttachment(name, description, data) {
4027
3569
  *
4028
3570
  * @internal
4029
3571
  */
4030
- var WebhookSeparator = class extends _seedcord_kit.BuilderComponent {
3572
+ var WebhookSeparator = class extends _seedcord_core.BuilderComponent {
4031
3573
  constructor() {
4032
3574
  super("separator");
4033
3575
  this.instance.setSpacing(discord_js.SeparatorSpacingSize.Small).setDivider(true);
@@ -4066,7 +3608,7 @@ let HandledException = class HandledException extends WebhookLog {
4066
3608
  };
4067
3609
  __decorate([(0, envapt.Envapt)("HANDLED_EXCEPTION_WEBHOOK_URL", { converter: (raw) => webhookUrlValidator$1(raw) }), __decorateMetadata("design:type", String)], HandledException, "handledExceptionWebhookUrl", void 0);
4068
3610
  HandledException = _HandledException = __decorate([Subscribe("handledException")], HandledException);
4069
- var HandledExceptionContainer = class extends _seedcord_kit.BuilderComponent {
3611
+ var HandledExceptionContainer = class extends _seedcord_core.BuilderComponent {
4070
3612
  constructor(data) {
4071
3613
  super("container");
4072
3614
  const { denial, uuid, source } = data;
@@ -4136,7 +3678,7 @@ let UnknownException = class UnknownException extends WebhookLog {
4136
3678
  };
4137
3679
  __decorate([(0, envapt.Envapt)("UNKNOWN_EXCEPTION_WEBHOOK_URL", { converter: (raw) => webhookUrlValidator(raw) }), __decorateMetadata("design:type", String)], UnknownException, "unknownExceptionWebhookUrl", void 0);
4138
3680
  UnknownException = _UnknownException = __decorate([Subscribe("unknownException")], UnknownException);
4139
- var UnhandledErrorContainer = class extends _seedcord_kit.BuilderComponent {
3681
+ var UnhandledErrorContainer = class extends _seedcord_core.BuilderComponent {
4140
3682
  constructor(data) {
4141
3683
  super("container");
4142
3684
  const { uuid, error, guild, user, metadata } = data;
@@ -4177,7 +3719,7 @@ var Bus = class extends Plugin {
4177
3719
  /** @internal */
4178
3720
  name = "Subscribers";
4179
3721
  isInitialized = false;
4180
- subscribersMap = new discord_js.Collection();
3722
+ subscribersMap = /* @__PURE__ */ new Map();
4181
3723
  executedOnceHandlers = /* @__PURE__ */ new Set();
4182
3724
  hmrHandler;
4183
3725
  constructor(core) {
@@ -4196,7 +3738,7 @@ var Bus = class extends Plugin {
4196
3738
  }
4197
3739
  }
4198
3740
  getArtifacts(ctor) {
4199
- return [Reflect.getMetadata(SubscribeMetadataKey, ctor).subscriber];
3741
+ return [Reflect.getMetadata(_seedcord_core_internal.SubscribeMetadataKey, ctor).subscriber];
4200
3742
  }
4201
3743
  /** @internal */
4202
3744
  async init() {
@@ -4230,7 +3772,7 @@ var Bus = class extends Plugin {
4230
3772
  }, this.logger);
4231
3773
  }
4232
3774
  registerSubscriber(handler) {
4233
- const options = Reflect.getMetadata(SubscribeMetadataKey, handler);
3775
+ const options = Reflect.getMetadata(_seedcord_core_internal.SubscribeMetadataKey, handler);
4234
3776
  let handlers = this.subscribersMap.get(options.subscriber);
4235
3777
  if (!handlers) {
4236
3778
  handlers = [];
@@ -4252,7 +3794,7 @@ var Bus = class extends Plugin {
4252
3794
  }
4253
3795
  isSubscriber(obj) {
4254
3796
  if (typeof obj !== "function") return false;
4255
- return obj.prototype instanceof Subscriber && Reflect.hasMetadata(SubscribeMetadataKey, obj);
3797
+ return obj.prototype instanceof Subscriber && Reflect.hasMetadata(_seedcord_core_internal.SubscribeMetadataKey, obj);
4256
3798
  }
4257
3799
  /**
4258
3800
  * Publishes an event to its subscribers and native listeners.
@@ -4286,6 +3828,11 @@ var Bus = class extends Plugin {
4286
3828
  }
4287
3829
  };
4288
3830
 
3831
+ //#endregion
3832
+ //#region src/version.ts
3833
+ /** Package version */
3834
+ const version = "0.16.0-next.4";
3835
+
4289
3836
  //#endregion
4290
3837
  //#region src/Seedcord.ts
4291
3838
  /**
@@ -4302,6 +3849,8 @@ var Seedcord = class Seedcord extends Pluggable {
4302
3849
  * @internal
4303
3850
  * */
4304
3851
  [_seedcord_types_internal.SeedcordBrand] = true;
3852
+ /** The framework package version this instance runs on. */
3853
+ version = version;
4305
3854
  static isInstantiated = false;
4306
3855
  /** @see {@link CoordinatedShutdown} */
4307
3856
  shutdown;
@@ -4311,7 +3860,7 @@ var Seedcord = class Seedcord extends Pluggable {
4311
3860
  bus;
4312
3861
  /** @see {@link Bot} */
4313
3862
  bot;
4314
- /** @see {@link RateLimiter} */
3863
+ /** @see {@link IRateLimiter} */
4315
3864
  rateLimiter;
4316
3865
  /** @see {@link HealthCheck} */
4317
3866
  healthCheck;
@@ -4330,21 +3879,18 @@ var Seedcord = class Seedcord extends Pluggable {
4330
3879
  const startup = new _seedcord_services.CoordinatedStartup();
4331
3880
  super(shutdown, startup);
4332
3881
  this.config = config;
4333
- (0, _seedcord_kit_internal.setBotColor)(config.botColor);
3882
+ (0, _seedcord_core_internal.setBotColor)(config.botColor);
4334
3883
  this.shutdown = shutdown;
4335
3884
  this.startup = startup;
4336
3885
  this.hmrManager = new HmrManager();
4337
3886
  this.hmrManager.init();
4338
3887
  this.bus = new Bus(this);
4339
3888
  this.bot = new Bot(this);
4340
- this.rateLimiter = new _seedcord_services.RateLimiter();
3889
+ this.rateLimiter = new _seedcord_rate_limiter.MemoryRateLimiter();
4341
3890
  this.healthCheck = new _seedcord_services.HealthCheck(this.shutdown, config.healthCheck);
4342
3891
  this.registerStartupTasks();
4343
3892
  }
4344
- /**
4345
- * Resets the singleton state.
4346
- * @internal
4347
- */
3893
+ /** @internal */
4348
3894
  static reset() {
4349
3895
  Seedcord.isInstantiated = false;
4350
3896
  }
@@ -4389,11 +3935,6 @@ var Seedcord = class Seedcord extends Pluggable {
4389
3935
  }
4390
3936
  };
4391
3937
 
4392
- //#endregion
4393
- //#region src/index.ts
4394
- /** Package version */
4395
- const version = "0.16.0-next.2";
4396
-
4397
3938
  //#endregion
4398
3939
  exports.ArraySource = ArraySource;
4399
3940
  exports.AutocompleteHandler = AutocompleteHandler;
@@ -4403,14 +3944,11 @@ exports.ButtonRoute = ButtonRoute;
4403
3944
  exports.CommandMentions = CommandMentions;
4404
3945
  exports.ContextMenuHandler = ContextMenuHandler;
4405
3946
  exports.ContextMenuRoute = ContextMenuRoute;
4406
- exports.Cooldown = Cooldown;
4407
3947
  exports.CursorSource = CursorSource;
4408
- exports.DmOnly = DmOnly;
4409
3948
  exports.Emojis = Emojis;
4410
3949
  exports.EventHandler = EventHandler;
4411
3950
  exports.EventMiddleware = EventMiddleware;
4412
3951
  exports.Gated = Gated;
4413
- exports.GuildOnly = GuildOnly;
4414
3952
  exports.HmrModuleHandler = HmrModuleHandler;
4415
3953
  exports.IgnoreBots = IgnoreBots;
4416
3954
  exports.InteractionHandler = InteractionHandler;
@@ -4420,11 +3958,15 @@ exports.MiddlewareType = MiddlewareType;
4420
3958
  exports.ModalHandler = ModalHandler;
4421
3959
  exports.ModalRoute = ModalRoute;
4422
3960
  exports.Nsfw = Nsfw;
4423
- exports.OwnerOnly = OwnerOnly;
4424
3961
  exports.Paginator = Paginator;
4425
3962
  exports.Pluggable = Pluggable;
4426
3963
  exports.Plugin = Plugin;
4427
- exports.RegisterCommand = RegisterCommand;
3964
+ Object.defineProperty(exports, 'RegisterCommand', {
3965
+ enumerable: true,
3966
+ get: function () {
3967
+ return _seedcord_core.RegisterCommand;
3968
+ }
3969
+ });
4428
3970
  exports.RegisterEvent = RegisterEvent;
4429
3971
  exports.ReplySender = ReplySender;
4430
3972
  exports.RequireBotPermissions = RequireBotPermissions;
@@ -4439,11 +3981,8 @@ exports.SlashRoute = SlashRoute;
4439
3981
  exports.Subscribe = Subscribe;
4440
3982
  exports.Subscriber = Subscriber;
4441
3983
  exports.WebhookLog = WebhookLog;
4442
- exports.and = and;
4443
3984
  exports.checkBotPermissions = checkBotPermissions;
4444
3985
  exports.checkPermissions = checkPermissions;
4445
- exports.defineEffectGate = defineEffectGate;
4446
- exports.defineGate = defineGate;
4447
3986
  exports.fetchGuildMember = fetchGuildMember;
4448
3987
  exports.fetchManyGuildMembers = fetchManyGuildMembers;
4449
3988
  exports.fetchManyUsers = fetchManyUsers;
@@ -4453,9 +3992,15 @@ exports.fetchUser = fetchUser;
4453
3992
  exports.getBotRole = getBotRole;
4454
3993
  exports.getConfirmation = getConfirmation;
4455
3994
  exports.hasPermsToAssign = hasPermsToAssign;
4456
- exports.or = or;
4457
3995
  exports.updateMemberRoles = updateMemberRoles;
4458
3996
  exports.version = version;
3997
+ Object.keys(_seedcord_core).forEach(function (k) {
3998
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
3999
+ enumerable: true,
4000
+ get: function () { return _seedcord_core[k]; }
4001
+ });
4002
+ });
4003
+
4459
4004
  Object.keys(_seedcord_errors).forEach(function (k) {
4460
4005
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
4461
4006
  enumerable: true,
@@ -4463,10 +4008,10 @@ Object.keys(_seedcord_errors).forEach(function (k) {
4463
4008
  });
4464
4009
  });
4465
4010
 
4466
- Object.keys(_seedcord_kit).forEach(function (k) {
4011
+ Object.keys(_seedcord_rate_limiter).forEach(function (k) {
4467
4012
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
4468
4013
  enumerable: true,
4469
- get: function () { return _seedcord_kit[k]; }
4014
+ get: function () { return _seedcord_rate_limiter[k]; }
4470
4015
  });
4471
4016
  });
4472
4017