@seedcord/core 0.11.0 → 0.12.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/Bus-VJw-QpoY.mjs +986 -0
- package/dist/Bus-VJw-QpoY.mjs.map +1 -0
- package/dist/{CoordinatedShutdown-H5YjZn8A.d.mts → CoordinatedShutdown-fPKLWjc5.d.mts} +13 -4
- package/dist/{CoordinatedStartup-CGnJrqcl.mjs → CoordinatedStartup-Zw_Lk7Zk.mjs} +22 -20
- package/dist/CoordinatedStartup-Zw_Lk7Zk.mjs.map +1 -0
- package/dist/Generated-ByC53_A2.d.mts +26 -0
- package/dist/HmrModuleHandler-Btgu8r96.mjs +165 -0
- package/dist/HmrModuleHandler-Btgu8r96.mjs.map +1 -0
- package/dist/{PluginHost-DB4j8unu.d.mts → PluginHost-DFnkIldj.d.mts} +43 -15
- package/dist/PluginHost-DTtxWRiL.mjs +552 -0
- package/dist/PluginHost-DTtxWRiL.mjs.map +1 -0
- package/dist/{PluginLifecycle-AhQ46NIr.mjs → PluginLifecycle-hx5zUc-P.mjs} +4 -4
- package/dist/PluginLifecycle-hx5zUc-P.mjs.map +1 -0
- package/dist/{ServerHost-DYeh0KTk.d.mts → ServerHost-B5o3ScCF.d.mts} +7 -6
- package/dist/{ServerHost-CtmAhEXn.mjs → ServerHost-CDaEDR4C.mjs} +17 -6
- package/dist/{ServerHost-CtmAhEXn.mjs.map → ServerHost-CDaEDR4C.mjs.map} +1 -1
- package/dist/bindViteEnv-NFzvdqlT.mjs +32 -0
- package/dist/{bindViteEnv-DWq5rftJ.mjs.map → bindViteEnv-NFzvdqlT.mjs.map} +1 -1
- package/dist/env-internal.index.mjs +1 -1
- package/dist/hmr.index.d.mts +20 -20
- package/dist/hmr.index.mjs +1 -1
- package/dist/{index-Du71Xx69.d.mts → index-DGHng1IN.d.mts} +115 -201
- package/dist/index.d.mts +321 -74
- package/dist/index.mjs +323 -102
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.d.mts +223 -83
- package/dist/internal.index.mjs +573 -74
- package/dist/internal.index.mjs.map +1 -1
- package/dist/node-internal.index.d.mts +8 -4
- package/dist/node-internal.index.mjs +19 -6
- package/dist/node-internal.index.mjs.map +1 -1
- package/dist/node.index.d.mts +3 -3
- package/dist/node.index.mjs +22 -28
- package/dist/node.index.mjs.map +1 -1
- package/dist/{phases-FTM69J3a.d.mts → phases-C2QCSqRu.d.mts} +164 -55
- package/dist/plugin.index.d.mts +3 -2
- package/dist/plugin.index.mjs +1 -1
- package/dist/subscribers-CGuVjbrg.mjs +982 -0
- package/dist/subscribers-CGuVjbrg.mjs.map +1 -0
- package/dist/{bindViteEnv-DWq5rftJ.mjs → usingCtx-Cf2cZi96.mjs} +1 -31
- package/package.json +14 -11
- package/dist/CoordinatedStartup-CGnJrqcl.mjs.map +0 -1
- package/dist/HmrModuleHandler-8ZC-UuZh.mjs +0 -162
- package/dist/HmrModuleHandler-8ZC-UuZh.mjs.map +0 -1
- package/dist/PluginHost-B8kxLOeb.mjs +0 -245
- package/dist/PluginHost-B8kxLOeb.mjs.map +0 -1
- package/dist/PluginLifecycle-AhQ46NIr.mjs.map +0 -1
- package/dist/phases-BauKJOTT.mjs +0 -31
- package/dist/phases-BauKJOTT.mjs.map +0 -1
- package/dist/publishDefault-D3dAyzZ9.mjs +0 -7
- package/dist/publishDefault-D3dAyzZ9.mjs.map +0 -1
- package/dist/subscribers-Ce3SWy23.mjs +0 -1913
- package/dist/subscribers-Ce3SWy23.mjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { I as DispatchContext, K as MiddlewareKind, c as AllSubscriptions, i as CoreBase, y as SubscriptionKey } from "./phases-C2QCSqRu.mjs";
|
|
2
2
|
import "reflect-metadata";
|
|
3
3
|
import { CustomId, CustomIdField } from "@seedcord/custom-id";
|
|
4
4
|
import { ActionRowBuilder, ButtonBuilder, ChannelSelectMenuBuilder, CheckboxBuilder, CheckboxGroupBuilder, CheckboxGroupOptionBuilder, ContainerBuilder, ContextMenuCommandBuilder, EmbedBuilder, FileBuilder, FileUploadBuilder, LabelBuilder, MediaGalleryBuilder, MentionableSelectMenuBuilder, ModalBuilder, RadioGroupBuilder, RadioGroupOptionBuilder, RoleSelectMenuBuilder, SectionBuilder, SeparatorBuilder, SlashCommandBuilder, SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, TextDisplayBuilder, TextInputBuilder, UserSelectMenuBuilder } from "@discordjs/builders";
|
|
5
5
|
import { APIApplicationCommand, APIMessageComponentEmoji, APIMessageTopLevelComponent, ApplicationCommandType, ChannelType, RESTPostAPIApplicationCommandsJSONBody, Snowflake } from "discord-api-types/v10";
|
|
6
|
+
import { Logger } from "@seedcord/logger";
|
|
6
7
|
import { EventFrequency, ILogger, ReplyFile, ReplyResponse } from "@seedcord/types";
|
|
7
|
-
import { Constructor, IsNever, LiteralUnion, NonEmptyTuple } from "type-fest";
|
|
8
|
+
import { Constructor, IsNever, IsUnion, LiteralUnion, NonEmptyTuple, Promisable, Simplify } from "type-fest";
|
|
8
9
|
//#region src/registries/ContextMenuRegistry.d.ts
|
|
9
10
|
/** The two context-menu command kinds Discord defines. */
|
|
10
11
|
type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Message;
|
|
@@ -19,7 +20,7 @@ type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Mess
|
|
|
19
20
|
*
|
|
20
21
|
* @example
|
|
21
22
|
* ```ts
|
|
22
|
-
* // seedcord-gen.
|
|
23
|
+
* // seedcord-gen.ts (emitted, committed)
|
|
23
24
|
* declare module '@seedcord/gateway' {
|
|
24
25
|
* interface UserContextMenuRegistry {
|
|
25
26
|
* 'View Profile': { cache: 'cached' };
|
|
@@ -77,7 +78,7 @@ interface SlashRouteEntry {
|
|
|
77
78
|
*
|
|
78
79
|
* @example
|
|
79
80
|
* ```ts
|
|
80
|
-
* // seedcord-gen.
|
|
81
|
+
* // seedcord-gen.ts (emitted, committed)
|
|
81
82
|
* declare module '@seedcord/gateway' {
|
|
82
83
|
* interface SlashRegistry {
|
|
83
84
|
* ban: { options: { target: { kind: 'user'; required: true } }; cache: 'cached' };
|
|
@@ -471,7 +472,7 @@ declare function serializeReply<TNative>(response: ReplyResponse<TNative> | stri
|
|
|
471
472
|
/**
|
|
472
473
|
* The transport-agnostic gate context, the scalar identity of the acting user resolvable from any
|
|
473
474
|
* transport's payload. Every field except `core` is nullable, since an event or DM may carry no
|
|
474
|
-
* guild or member. Each transport extends it with its own
|
|
475
|
+
* guild or member. Each transport extends it with its own context. For example, the gateway adds the djs
|
|
475
476
|
* `user`/`guild`/`member` objects and the live interaction or event payload.
|
|
476
477
|
*
|
|
477
478
|
* @example
|
|
@@ -501,19 +502,9 @@ interface GateContextBase {
|
|
|
501
502
|
* channel-scoped permissions the payload contains, and on a gateway event they're the member's guild-level ones.
|
|
502
503
|
*/
|
|
503
504
|
readonly memberPermissions: bigint | null;
|
|
504
|
-
/**
|
|
505
|
-
* The bot's permissions in the invoked channel, the wire `app_permissions` value. Null on gateway events.
|
|
506
|
-
*/
|
|
507
|
-
readonly appPermissions: bigint | null;
|
|
508
|
-
/**
|
|
509
|
-
* The handler's own route, as `kind:route` (`slash:daily`, `button:confirm`). A handler registered
|
|
510
|
-
* on several reports the one this dispatch matched. Null when the handler declares none, which
|
|
511
|
-
* covers a plain event handler, the unhandled default, and a gate run outside a handler.
|
|
512
|
-
*/
|
|
513
|
-
readonly declaredRoute: string | null;
|
|
514
505
|
/**
|
|
515
506
|
* The bag for this dispatch, the same instance the handler and its middleware hold. Every middleware
|
|
516
|
-
* runs before the first gate. A gate therefore
|
|
507
|
+
* runs before the first gate. A gate can therefore read what a middleware wrote.
|
|
517
508
|
*/
|
|
518
509
|
readonly dispatch: DispatchContext;
|
|
519
510
|
}
|
|
@@ -535,10 +526,25 @@ interface GuildPermissionsContext extends GateContextBase {
|
|
|
535
526
|
*/
|
|
536
527
|
readonly memberGuildPermissions: bigint | null;
|
|
537
528
|
/**
|
|
538
|
-
* The bot's base permission set from the transport's cache.
|
|
529
|
+
* The bot's base permission set from the transport's cache. It's `0n` in a guild the bot isn't in. It's null
|
|
530
|
+
* when the guild is cached but the bot's member isn't.
|
|
539
531
|
*/
|
|
540
532
|
readonly appGuildPermissions: bigint | null;
|
|
541
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* The context an interaction provides on both transports, where Discord always sends the bot's channel
|
|
536
|
+
* permissions. A gate that requires it fits no event handler.
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* // the default channel scope returns a Gate<AppPermissionsContext>
|
|
541
|
+
* \@Gated(RequireBotPermissions([PermissionFlagsBits.ManageMessages]))
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
interface AppPermissionsContext extends GateContextBase {
|
|
545
|
+
/** The bot's permissions in the invoked channel, the wire `app_permissions` value. */
|
|
546
|
+
readonly appPermissions: bigint;
|
|
547
|
+
}
|
|
542
548
|
declare const GateBrand: unique symbol;
|
|
543
549
|
/**
|
|
544
550
|
* A precondition attached to a handler. It refuses by throwing a `Notice` (a reply) or a `Silence`
|
|
@@ -570,13 +576,12 @@ interface Gate<Ctx extends GateContextBase = GateContextBase, Name extends strin
|
|
|
570
576
|
readonly [GateBrand]: true;
|
|
571
577
|
}
|
|
572
578
|
/**
|
|
573
|
-
* A gate
|
|
574
|
-
*
|
|
575
|
-
* gate set passes. {@link Cooldown} is the catalog gate that returns one. Build one with
|
|
579
|
+
* A gate whose `check` method can refuse a request without applying its side effect. `commit` applies
|
|
580
|
+
* the effect after every gate passes. {@link Cooldown} is the catalog gate that returns one. Build one with
|
|
576
581
|
* {@link defineEffectGate}.
|
|
577
582
|
*
|
|
578
583
|
* @typeParam Ctx - The context both `check` and `commit` require. A field missing from it fails to compile.
|
|
579
|
-
* @typeParam Name - The
|
|
584
|
+
* @typeParam Name - The literal name a mismatch error prints.
|
|
580
585
|
*
|
|
581
586
|
* @example
|
|
582
587
|
* ```ts
|
|
@@ -633,11 +638,11 @@ interface EffectGate<Ctx extends GateContextBase = GateContextBase, Name extends
|
|
|
633
638
|
* });
|
|
634
639
|
* ```
|
|
635
640
|
*/
|
|
636
|
-
declare function defineGate<const Name extends string, Ctx extends GateContextBase = GateContextBase>(name: Name, fn: (ctx: Ctx) =>
|
|
641
|
+
declare function defineGate<const Name extends string, Ctx extends GateContextBase = GateContextBase>(name: Name, fn: (ctx: Ctx) => Promisable<void>): Gate<Ctx, Name>;
|
|
637
642
|
/**
|
|
638
643
|
* Builds an {@link EffectGate} from a `check` and a `commit`. `check` peeks and refuses by throwing, and
|
|
639
644
|
* `commit` applies the side effect, running only once the whole gate set passes so a later refusal never
|
|
640
|
-
* commits. In an `or`,
|
|
645
|
+
* commits. In an `or`, seedcord rolls back the commit a refusing gate queued. This is how {@link Cooldown} peeks
|
|
641
646
|
* in `check` and charges the slot in `commit`.
|
|
642
647
|
*
|
|
643
648
|
* @typeParam Name - The gate's literal name, used to name a mismatch error.
|
|
@@ -669,7 +674,7 @@ declare function defineGate<const Name extends string, Ctx extends GateContextBa
|
|
|
669
674
|
* }
|
|
670
675
|
* ```
|
|
671
676
|
*/
|
|
672
|
-
declare function defineEffectGate<const Name extends string, Ctx extends GateContextBase = GateContextBase>(name: Name, check: (ctx: Ctx) =>
|
|
677
|
+
declare function defineEffectGate<const Name extends string, Ctx extends GateContextBase = GateContextBase>(name: Name, check: (ctx: Ctx) => Promisable<void>, commit: (ctx: Ctx) => Promisable<void>): EffectGate<Ctx, Name>;
|
|
673
678
|
/**
|
|
674
679
|
* The context a {@link Gate} requires.
|
|
675
680
|
*
|
|
@@ -688,164 +693,9 @@ type TwoOrMore<Item> = readonly [Item, Item, ...Item[]];
|
|
|
688
693
|
type GateName<TGate> = TGate extends Gate<GateContextBase, infer Name> ? Name : string;
|
|
689
694
|
type Grouped<Name extends string> = Name extends `${string} & ${string}` | `${string} | ${string}` ? `(${Name})` : Name;
|
|
690
695
|
type JoinNames<Gates extends readonly Gate<GateContextBase>[], Sep extends string> = Gates extends readonly [infer Only extends Gate<GateContextBase>] ? Grouped<GateName<Only>> : Gates extends readonly [infer First extends Gate<GateContextBase>, ...infer Rest extends readonly Gate<GateContextBase>[]] ? `${Grouped<GateName<First>>}${Sep}${JoinNames<Rest, Sep>}` : string;
|
|
691
|
-
type GateMismatch<Name extends string, Want extends string, Got extends string> = `gate '${Name}'
|
|
696
|
+
type GateMismatch<Name extends string, Want extends string, Got extends string> = `gate '${Name}' needs a handler of kind ${Want}, but this handler's kind is ${Got}`;
|
|
692
697
|
type GateFitsWith<Provided, ProvidedLabel extends string, TGate, ReqLabel extends string> = [Provided] extends [RequiredOf<TGate>] ? TGate : Constructor<[GateMismatch<GateName<TGate>, ReqLabel, ProvidedLabel>]>;
|
|
693
698
|
//#endregion
|
|
694
|
-
//#region src/gates/catalog/options.d.ts
|
|
695
|
-
/**
|
|
696
|
-
* The override a catalog gate accepts. A one-line `message` reword or a full `notice` replacement. Accepted by
|
|
697
|
-
* the agnostic catalog gates and, nested per refusal, by {@link RequireRole}. {@link RequirePermissions} and
|
|
698
|
-
* {@link RequireBotPermissions} take `RequirePermissionsOptions` instead.
|
|
699
|
-
*
|
|
700
|
-
* @example
|
|
701
|
-
* ```ts
|
|
702
|
-
* // reword the default refusal
|
|
703
|
-
* OwnerOnly({ message: 'Bot owners only.' });
|
|
704
|
-
* ```
|
|
705
|
-
*
|
|
706
|
-
* @example
|
|
707
|
-
* ```ts
|
|
708
|
-
* // replace the refusal entirely, for example a translated Notice
|
|
709
|
-
* GuildOnly({ notice: new MyTranslatedNotice() });
|
|
710
|
-
* ```
|
|
711
|
-
*/
|
|
712
|
-
interface GateNoticeOptions {
|
|
713
|
-
/** Reword the default refusal, keeping its embed styling. */
|
|
714
|
-
message?: string;
|
|
715
|
-
/** Replace the default refusal Notice entirely, for full control or a translated copy. */
|
|
716
|
-
notice?: Notice;
|
|
717
|
-
}
|
|
718
|
-
declare function pickNotice(options: GateNoticeOptions | undefined, makeDefault: (message?: string) => Notice): Notice;
|
|
719
|
-
//#endregion
|
|
720
|
-
//#region src/permissions/bits.d.ts
|
|
721
|
-
/**
|
|
722
|
-
* The permission flag bits a caller or the bot must hold. Pass the `PermissionFlagsBits` values from
|
|
723
|
-
* `discord-api-types/v10` (or `discord.js`).
|
|
724
|
-
*/
|
|
725
|
-
type PermissionScope = readonly bigint[];
|
|
726
|
-
declare const PermissionNames: Map<bigint, string>;
|
|
727
|
-
//#endregion
|
|
728
|
-
//#region src/gates/catalog/permissions.d.ts
|
|
729
|
-
/**
|
|
730
|
-
* Options for {@link RequirePermissions} and {@link RequireBotPermissions}.
|
|
731
|
-
*/
|
|
732
|
-
interface RequirePermissionsOptions {
|
|
733
|
-
/**
|
|
734
|
-
* The set the check reads. `'channel'` reads the effective channel set the payload carries, what
|
|
735
|
-
* Discord enforces in the invoked channel. `'guild'` reads the base set from roles, available on the
|
|
736
|
-
* gateway transport only.
|
|
737
|
-
*
|
|
738
|
-
* @defaultValue `'channel'`
|
|
739
|
-
*/
|
|
740
|
-
in?: 'channel' | 'guild';
|
|
741
|
-
/** Reword or replace the refusal shown when the set is unavailable (outside a guild, or unresolved inside one). */
|
|
742
|
-
notInGuild?: GateNoticeOptions;
|
|
743
|
-
/** Reword or replace the refusal shown when a permission is missing. */
|
|
744
|
-
missing?: GateNoticeOptions;
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
* Options for {@link RequireRole}.
|
|
748
|
-
*/
|
|
749
|
-
interface RequireRoleOptions {
|
|
750
|
-
/** Reword or replace the refusal shown outside a guild. */
|
|
751
|
-
notInGuild?: GateNoticeOptions;
|
|
752
|
-
/** Reword or replace the refusal shown when the caller lacks the role. */
|
|
753
|
-
missingRole?: GateNoticeOptions;
|
|
754
|
-
}
|
|
755
|
-
/**
|
|
756
|
-
* Requires the caller to hold every permission in `scope`. Refuses outside a guild first, then when a
|
|
757
|
-
* permission is missing. The Administrator bit passes any scope.
|
|
758
|
-
*
|
|
759
|
-
* The default `'channel'` scope reads the effective channel set the payload carries, what Discord enforces
|
|
760
|
-
* in the invoked channel. The `'guild'` scope reads the base set from roles and requires a
|
|
761
|
-
* {@link GuildPermissionsContext}, so it fits a gateway handler only.
|
|
762
|
-
*
|
|
763
|
-
* @param scope - The permission flag bits the caller must all hold.
|
|
764
|
-
* @param options - Pick the scope with `in`, and override each refusal with `notInGuild` or `missing`.
|
|
765
|
-
*
|
|
766
|
-
* @see the `@Gated` decorator from your transport package
|
|
767
|
-
*
|
|
768
|
-
* @example
|
|
769
|
-
* ```ts
|
|
770
|
-
* import { PermissionFlagsBits } from 'discord-api-types/v10';
|
|
771
|
-
*
|
|
772
|
-
* \@Gated(RequirePermissions([PermissionFlagsBits.BanMembers]))
|
|
773
|
-
* \@SlashRoute('ban')
|
|
774
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
775
|
-
* async execute() {
|
|
776
|
-
* // ...
|
|
777
|
-
* }
|
|
778
|
-
* }
|
|
779
|
-
* ```
|
|
780
|
-
*
|
|
781
|
-
* @example
|
|
782
|
-
* ```ts
|
|
783
|
-
* // the base set from roles, on a gateway handler
|
|
784
|
-
* RequirePermissions([PermissionFlagsBits.BanMembers], { in: 'guild' });
|
|
785
|
-
* ```
|
|
786
|
-
*/
|
|
787
|
-
declare function RequirePermissions(scope: PermissionScope, options: RequirePermissionsOptions & {
|
|
788
|
-
in: 'guild';
|
|
789
|
-
}): Gate<GuildPermissionsContext, 'RequirePermissions'>;
|
|
790
|
-
declare function RequirePermissions(scope: PermissionScope, options?: RequirePermissionsOptions & {
|
|
791
|
-
in?: 'channel';
|
|
792
|
-
}): Gate<GateContextBase, 'RequirePermissions'>;
|
|
793
|
-
/**
|
|
794
|
-
* Requires the bot to hold every permission in `scope`. Refuses outside a guild first, then when a
|
|
795
|
-
* permission is missing. The Administrator bit passes any scope.
|
|
796
|
-
*
|
|
797
|
-
* The default `'channel'` scope reads the bot's effective channel set (wire `app_permissions`), what
|
|
798
|
-
* Discord enforces in the invoked channel. The `'guild'` scope reads the bot's base set from roles and
|
|
799
|
-
* requires a {@link GuildPermissionsContext}, fitting a gateway handler only. `app_permissions` is
|
|
800
|
-
* absent on gateway events, the channel scope refuses there as unresolved, use `in: 'guild'` on an
|
|
801
|
-
* event handler.
|
|
802
|
-
*
|
|
803
|
-
* @param scope - The permission flag bits the bot must all hold.
|
|
804
|
-
* @param options - Pick the scope with `in`, and override each refusal with `notInGuild` or `missing`.
|
|
805
|
-
*
|
|
806
|
-
* @see the `@Gated` decorator from your transport package
|
|
807
|
-
*
|
|
808
|
-
* @example
|
|
809
|
-
* ```ts
|
|
810
|
-
* import { PermissionFlagsBits } from 'discord-api-types/v10';
|
|
811
|
-
*
|
|
812
|
-
* \@Gated(RequireBotPermissions([PermissionFlagsBits.ManageMessages]))
|
|
813
|
-
* \@SlashRoute('purge')
|
|
814
|
-
* class PurgeHandler extends SlashHandler<'purge'> {
|
|
815
|
-
* async execute() {
|
|
816
|
-
* // ...
|
|
817
|
-
* }
|
|
818
|
-
* }
|
|
819
|
-
* ```
|
|
820
|
-
*/
|
|
821
|
-
declare function RequireBotPermissions(scope: PermissionScope, options: RequirePermissionsOptions & {
|
|
822
|
-
in: 'guild';
|
|
823
|
-
}): Gate<GuildPermissionsContext, 'RequireBotPermissions'>;
|
|
824
|
-
declare function RequireBotPermissions(scope: PermissionScope, options?: RequirePermissionsOptions & {
|
|
825
|
-
in?: 'channel';
|
|
826
|
-
}): Gate<GateContextBase, 'RequireBotPermissions'>;
|
|
827
|
-
/**
|
|
828
|
-
* Requires the caller to hold `roleId`, read from the member's role ids. Refuses outside a guild first,
|
|
829
|
-
* then when the role is missing. Roles are guild-global, so there is no scope dimension.
|
|
830
|
-
*
|
|
831
|
-
* @param roleId - The role snowflake the caller must hold.
|
|
832
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-role one with `missingRole`.
|
|
833
|
-
*
|
|
834
|
-
* @see the `@Gated` decorator from your transport package
|
|
835
|
-
*
|
|
836
|
-
* @example
|
|
837
|
-
* ```ts
|
|
838
|
-
* \@Gated(RequireRole('123456789012345678'))
|
|
839
|
-
* \@SlashRoute('vip')
|
|
840
|
-
* class VipHandler extends SlashHandler<'vip'> {
|
|
841
|
-
* async execute() {
|
|
842
|
-
* // ...
|
|
843
|
-
* }
|
|
844
|
-
* }
|
|
845
|
-
* ```
|
|
846
|
-
*/
|
|
847
|
-
declare function RequireRole(roleId: string, options?: RequireRoleOptions): Gate<GateContextBase, 'RequireRole'>;
|
|
848
|
-
//#endregion
|
|
849
699
|
//#region src/miscellaneous/ResolvedEmoji.d.ts
|
|
850
700
|
/**
|
|
851
701
|
* A resolved custom emoji. Renders as `<:name:id>` in message content, or `<a:name:id>` when animated,
|
|
@@ -871,10 +721,10 @@ type ChoiceValueOf<Entry> = Entry extends {
|
|
|
871
721
|
kind: 'integer' | 'number';
|
|
872
722
|
} ? number : never;
|
|
873
723
|
/** the focused option. `value` is the raw partial discord delivers mid-type, always a string regardless of kind. */
|
|
874
|
-
|
|
724
|
+
type FocusedField<Route extends keyof SlashRegistry> = Simplify<{
|
|
875
725
|
name: AutocompletableNames<Route>;
|
|
876
726
|
value: string;
|
|
877
|
-
}
|
|
727
|
+
}>;
|
|
878
728
|
type NamesOfKind<Route extends keyof SlashRegistry, Kind extends OptionKind> = Route extends unknown ? { [Name in keyof Row<Route>]: Row<Route>[Name] extends {
|
|
879
729
|
kind: Kind;
|
|
880
730
|
} ? Name : never; }[keyof Row<Route>] : never;
|
|
@@ -908,6 +758,66 @@ type PageCursor<Prefix extends string> = CustomId<Prefix, {
|
|
|
908
758
|
/** Build the page cursor for a paginator. */
|
|
909
759
|
declare function pageCursor<Prefix extends string>(prefix: Prefix): PageCursor<Prefix>;
|
|
910
760
|
//#endregion
|
|
761
|
+
//#region src/handlers/runCase.d.ts
|
|
762
|
+
type ResolvedReturn<Case> = Case extends ((...args: never[]) => infer Result) ? Awaited<Result> : never;
|
|
763
|
+
type CaseReturn<Ret> = [Ret] extends [never] ? unknown : Promisable<Ret>;
|
|
764
|
+
type MatchResult<Ret, Cases> = [Ret] extends [never] ? ResolvedReturn<Cases[keyof Cases]> : Ret;
|
|
765
|
+
type ShapeKey<Shape> = keyof Shape | `${Extract<keyof Shape, string>}`;
|
|
766
|
+
type OnlyCases<Cases, Shape> = Cases & Record<Exclude<keyof Cases, ShapeKey<Shape>>, never>;
|
|
767
|
+
declare function runCase<Result>(handler: object, cases: object, kind: string, value: string, ...args: unknown[]): Promise<Result>;
|
|
768
|
+
//#endregion
|
|
769
|
+
//#region src/subscribers/Subscriber.d.ts
|
|
770
|
+
type SubscriberMatchCases<Keys extends SubscriptionKey, Ret> = { [Key in Keys]: (data: AllSubscriptions[Key]) => CaseReturn<Ret>; };
|
|
771
|
+
type SingleKeyData<Keys extends SubscriptionKey> = IsUnion<Keys> extends true ? never : AllSubscriptions[Keys];
|
|
772
|
+
/**
|
|
773
|
+
* Abstract base class for handling application subscribers.
|
|
774
|
+
*
|
|
775
|
+
* Pass the subscription key(s) as the generic, the same one(s) as `@Subscribe`. On a single-key subscriber, read
|
|
776
|
+
* `this.data` directly. On a subscriber for several keys, branch with `this.match`, keyed by subscription key.
|
|
777
|
+
*
|
|
778
|
+
* @typeParam Keys - One or more subscription keys, like `'userJoin'` or `'userJoin' | 'userLeave'`.
|
|
779
|
+
* @typeParam TCore - The transport's Core
|
|
780
|
+
*/
|
|
781
|
+
declare abstract class Subscriber<in out Keys extends SubscriptionKey, TCore extends CoreBase> {
|
|
782
|
+
#private;
|
|
783
|
+
protected readonly core: TCore;
|
|
784
|
+
protected readonly key: Keys;
|
|
785
|
+
protected readonly logger: Logger;
|
|
786
|
+
constructor(payload: AllSubscriptions[Keys], core: TCore, key: Keys);
|
|
787
|
+
/** The published payload. It's `never` on a subscriber for several keys, where `this.match` reads it. */
|
|
788
|
+
protected get data(): SingleKeyData<Keys>;
|
|
789
|
+
/**
|
|
790
|
+
* Executes the subscriber handler logic.
|
|
791
|
+
*/
|
|
792
|
+
abstract execute(): Promise<void>;
|
|
793
|
+
/**
|
|
794
|
+
* Run the case for the published key. Use this only when the subscriber is registered for several
|
|
795
|
+
* keys. On a single-key subscriber, read `this.data` directly.
|
|
796
|
+
*
|
|
797
|
+
* Provide one case per registered key. Each case receives that key's own payload. A missing key or an unknown
|
|
798
|
+
* key is a compile error.
|
|
799
|
+
*
|
|
800
|
+
* @typeParam Ret - The type that every case must return. Leave it out to get the union of what the cases return.
|
|
801
|
+
* @throws A **SeedcordTypeError** with `MatchCaseMissing` when the published key doesn't have a case.
|
|
802
|
+
*
|
|
803
|
+
* @example
|
|
804
|
+
* ```ts
|
|
805
|
+
* import { Subscribe, Subscriber } from '@seedcord/gateway';
|
|
806
|
+
*
|
|
807
|
+
* \@Subscribe(['interactionDispatched'], ['eventDispatched'])
|
|
808
|
+
* class Metrics extends Subscriber<'interactionDispatched' | 'eventDispatched'> {
|
|
809
|
+
* async execute() {
|
|
810
|
+
* await this.match({
|
|
811
|
+
* interactionDispatched: (data) => this.logger.info(data.routeId),
|
|
812
|
+
* eventDispatched: (data) => this.logger.info(data.name)
|
|
813
|
+
* });
|
|
814
|
+
* }
|
|
815
|
+
* }
|
|
816
|
+
* ```
|
|
817
|
+
*/
|
|
818
|
+
protected match<Ret = never, Cases extends SubscriberMatchCases<Keys, Ret> = SubscriberMatchCases<Keys, Ret>>(cases: OnlyCases<Cases, SubscriberMatchCases<Keys, Ret>>): Promise<MatchResult<Ret, Cases>>;
|
|
819
|
+
}
|
|
820
|
+
//#endregion
|
|
911
821
|
//#region src/subscribers/decorators/Subscribe.d.ts
|
|
912
822
|
/**
|
|
913
823
|
* Options accepted by the `@Subscribe` decorator.
|
|
@@ -920,32 +830,36 @@ interface SubscribeOptions {
|
|
|
920
830
|
*/
|
|
921
831
|
readonly frequency?: EventFrequency | undefined;
|
|
922
832
|
}
|
|
833
|
+
type SubscribeSpec<Key extends SubscriptionKey> = readonly [key: Key, options?: SubscribeOptions];
|
|
923
834
|
/**
|
|
924
|
-
* Registers a subscriber
|
|
835
|
+
* Registers a subscriber class with one or more subscription keys.
|
|
925
836
|
*
|
|
926
|
-
*
|
|
927
|
-
* registration and execution when the subscriber is emitted.
|
|
837
|
+
* Supply one `[key, options?]` tuple per key. The subscriber's generic must list the same keys.
|
|
928
838
|
*
|
|
929
|
-
* @typeParam TSubscriber - The subscriber event name to register for
|
|
930
|
-
* @param subscriber - The subscriber event name to register for
|
|
931
|
-
* @param options - Options to configure the subscriber handler registration.
|
|
932
839
|
* @decorator
|
|
933
840
|
* @example
|
|
934
|
-
* ```
|
|
935
|
-
* \@Subscribe('userJoin')
|
|
841
|
+
* ```ts
|
|
842
|
+
* \@Subscribe(['userJoin'])
|
|
936
843
|
* class WelcomeHandler extends Subscriber<'userJoin'> {
|
|
937
|
-
*
|
|
938
|
-
*
|
|
844
|
+
* async execute() {
|
|
845
|
+
* this.logger.info(`${this.data.userId} joined`);
|
|
846
|
+
* }
|
|
939
847
|
* }
|
|
940
848
|
* ```
|
|
941
849
|
* @example
|
|
942
850
|
* ```ts
|
|
943
|
-
* \@Subscribe('userJoin', { frequency: 'once' })
|
|
944
|
-
*
|
|
945
|
-
*
|
|
851
|
+
* \@Subscribe(['userJoin', { frequency: 'once' }], ['userLeave'])
|
|
852
|
+
* class Presence extends Subscriber<'userJoin' | 'userLeave'> {
|
|
853
|
+
* async execute() {
|
|
854
|
+
* await this.match({
|
|
855
|
+
* userJoin: (data) => this.logger.info(`${data.userId} joined`),
|
|
856
|
+
* userLeave: (data) => this.logger.info(`${data.userId} left`)
|
|
857
|
+
* });
|
|
858
|
+
* }
|
|
859
|
+
* }
|
|
946
860
|
* ```
|
|
947
861
|
*/
|
|
948
|
-
declare function Subscribe<
|
|
862
|
+
declare function Subscribe<const Defs extends readonly SubscribeSpec<SubscriptionKey>[]>(...defs: Defs): <HandlerCtor extends Constructor<Subscriber<Defs[number][0], CoreBase>>>(constructor: HandlerCtor) => void;
|
|
949
863
|
//#endregion
|
|
950
864
|
//#region src/subscribers/bases/WebhookSender.d.ts
|
|
951
865
|
/** A file attached to a webhook report. */
|
|
@@ -990,7 +904,7 @@ interface WebhookReport {
|
|
|
990
904
|
* resolves the url, validates it, reuses one sender per url, and sends. Registration skips a reporter
|
|
991
905
|
* whose variable is unset and warns at boot.
|
|
992
906
|
*
|
|
993
|
-
* @typeParam KeyOfSubscribers - The subscription key this reporter receives
|
|
907
|
+
* @typeParam KeyOfSubscribers - The subscription key or keys that this reporter receives, the same ones as `@Subscribe`
|
|
994
908
|
* @typeParam TCore - The transport's Core
|
|
995
909
|
*/
|
|
996
910
|
declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey, TCore extends CoreBase> extends Subscriber<KeyOfSubscribers, TCore> {
|
|
@@ -1025,7 +939,7 @@ declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey, TCor
|
|
|
1025
939
|
* @decorator
|
|
1026
940
|
* @example
|
|
1027
941
|
* ```ts
|
|
1028
|
-
* \@Subscribe('memberBanned')
|
|
942
|
+
* \@Subscribe(['memberBanned'])
|
|
1029
943
|
* \@WebhookUrl('BAN_LOG_WEBHOOK_URL')
|
|
1030
944
|
* class BanLog extends WebhookLog<'memberBanned'> {
|
|
1031
945
|
* report() {
|
|
@@ -1034,7 +948,7 @@ declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey, TCor
|
|
|
1034
948
|
* }
|
|
1035
949
|
* ```
|
|
1036
950
|
*/
|
|
1037
|
-
declare function WebhookUrl(envKey: string): <
|
|
951
|
+
declare function WebhookUrl(envKey: string): <Keys extends SubscriptionKey>(constructor: Constructor<WebhookLog<Keys, CoreBase>>) => void;
|
|
1038
952
|
//#endregion
|
|
1039
|
-
export {
|
|
1040
|
-
//# sourceMappingURL=index-
|
|
953
|
+
export { ContextMenuInfo as $, RequiredOf as A, SlashOption as At, InteractionMiddlewareMetadata as B, JoinNames as C, BuilderComponent as Ct, Gate as D, CacheFor as Dt, EffectGate as E, RowType as Et, DispatchResult as F, MessageContextMenuRegistry as Ft, ComponentDefsBrand as G, RegisterInteractionMiddleware as H, EventDispatchResult as I, NamesFor as It, ContextMenuNamesBrand as J, ComponentKindBrand as K, HandlerOutcome as L, UserContextMenuRegistry as Lt, defineGate as M, SlashRouteEntry as Mt, SerializedReply as N, ContextMenuKind as Nt, GateContextBase as O, OptionKind as Ot, serializeReply as P, MenuCacheFor as Pt, Commands as Q, HandlerResult as R, IntersectRequired as S, RegisterCommand as St, AppPermissionsContext as T, BuilderType as Tt, interactionMiddlewareMetaOf as U, InteractionMiddlewareOptions as V, AutocompleteRouteBrand as W, SlashRouteBrand as X, MiddlewareKindsBrand as Y, CommandInfo as Z, ChoiceValueOf as _, scopeIdsOf as _t, Subscribe as a, CommandRef as at, ResolvedEmoji as b, CommandMeta as bt, CaseReturn as c, commandRefOf as ct, runCase as d, CommandBuilder as dt, ContextMenus as et, PAGE_MAX as f, DeployResult as ft, AutocompleteOptions as g, globalFirst as gt, AutocompletableNames as h, commandsRoute as ht, WebhookFile as i, warnLinks as it, defineEffectGate as j, SlashRegistry as jt, GuildPermissionsContext as k, RouteCache as kt, MatchResult as l, indexById as lt, pageCursor as m, ScopeId as mt, WebhookLog as n, InjectedContextMenuMap as nt, SubscribeOptions as o, LinkedCommands as ot, PageCursor as p, GLOBAL_ID as pt, ContextMenuKindBrand as q, WebhookReport as r, installLinks as rt, Subscriber as s, commandKey as st, WebhookUrl as t, InjectedCommandMap as tt, OnlyCases as u, linkCommands as ut, EntryFor as v, skippedNote as vt, TwoOrMore as w, RowComponent as wt, GateFitsWith as x, GuildTarget as xt, FocusedField as y, resolveDeployTarget as yt, AnyMiddlewareCtor as z };
|
|
954
|
+
//# sourceMappingURL=index-DGHng1IN.d.mts.map
|