@seedcord/core 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/{Bus-BVwmKc-A.mjs → Bus-yJGE6Fs2.mjs} +78 -78
  2. package/dist/{Bus-BVwmKc-A.mjs.map → Bus-yJGE6Fs2.mjs.map} +1 -1
  3. package/dist/{Pluggable-Cf5-WWmW.mjs → Pluggable-BI_LQuPm.mjs} +3 -3
  4. package/dist/{Pluggable-Cf5-WWmW.mjs.map → Pluggable-BI_LQuPm.mjs.map} +1 -1
  5. package/dist/{Pluggable-DFNUIlJM.d.mts → Pluggable-bFCmT4oB.d.mts} +3 -3
  6. package/dist/{Plugin-C6oMqWf8.mjs → Plugin-B0SRHzMX.mjs} +2 -2
  7. package/dist/{Plugin-C6oMqWf8.mjs.map → Plugin-B0SRHzMX.mjs.map} +1 -1
  8. package/dist/{Plugin-CG9pWbPF.d.mts → Plugin-BW2JH2_h.d.mts} +2 -2
  9. package/dist/{cursor-BcRfmTSo.d.mts → cursor-CO_MTgdZ.d.mts} +5 -203
  10. package/dist/{cursor-GBUYz3jk.mjs → cursor-CaT051ii.mjs} +6 -472
  11. package/dist/cursor-CaT051ii.mjs.map +1 -0
  12. package/dist/{index-ZzdQafFv.d.mts → index-CvneCObW.d.mts} +2 -2
  13. package/dist/index.d.mts +6 -5
  14. package/dist/index.mjs +42 -7
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/internal.index.d.mts +6 -5
  17. package/dist/internal.index.mjs +4 -4
  18. package/dist/node-internal.index.d.mts +4 -4
  19. package/dist/node-internal.index.mjs +6 -6
  20. package/dist/node.index.d.mts +1 -1
  21. package/dist/node.index.mjs +2 -2
  22. package/dist/{phases-F8yvPd60.d.mts → phases-C5Steaa2.d.mts} +56 -56
  23. package/dist/plugin.index.d.mts +1 -1
  24. package/dist/plugin.index.mjs +1 -1
  25. package/dist/{slashRouteLeaves-CbYRwqMY.mjs → slashRouteLeaves-BQmbFm-S.mjs} +2 -2
  26. package/dist/{slashRouteLeaves-CbYRwqMY.mjs.map → slashRouteLeaves-BQmbFm-S.mjs.map} +1 -1
  27. package/dist/{subscribers-CGGQkUfM.mjs → subscribers-DVa-Pr45.mjs} +3 -3
  28. package/dist/{subscribers-CGGQkUfM.mjs.map → subscribers-DVa-Pr45.mjs.map} +1 -1
  29. package/package.json +8 -7
  30. package/dist/cursor-GBUYz3jk.mjs.map +0 -1
@@ -1,12 +1,13 @@
1
- import { $ as Promisable, A as serializeReply, B as contextMenuRouteOf, C as Gate, F as ContextMenuNamesBrand, G as AnyCustomId, H as selectMenuRouteOf, I as SlashRouteBrand, J as decodeFor, L as RoutableConstructor, M as ComponentDefsBrand, N as ComponentKindBrand, P as ContextMenuKindBrand, U as storeComponentRoute, V as interactionRoutesOf, W as storeInteractionRoute, X as DecodedParams, Y as prefixOf, Z as CommandMeta, _ as pickNotice, at as CacheFor, c as FocusedField, ct as SlashOption, et as IsNever, ft as MenuCacheFor, i as AutocompletableNames, j as AutocompleteRouteBrand, k as SerializedReply, lt as SlashRegistry, m as PermissionNames, mt as NamesFor, n as PageCursor, o as ChoiceValueOf, ot as OptionKind, r as pageCursor, s as EntryFor, st as RouteCache, t as PAGE_MAX, tt as BuilderComponent, ut as SlashRouteEntry, v as GateFitsWith, w as GateContextBase, z as areRoutes } from "./cursor-BcRfmTSo.mjs";
1
+ import { A as UnregisterSubscriber, B as SubscribeMetadataKey, C as ReplyMethod, D as RegisterDefaults, E as AckTrace, F as GatedMetadataKey, H as Notice, I as InteractionMetadataKey, L as InteractionRouteKeys, M as PublishDefault, N as CommandMetadataKey, O as RegisterSubscriber, P as EventMetadataKey, R as InteractionRoutes, S as AckState, T as sendTarget, V as WebhookUrlMetadataKey, a as StoredSubscriberCtor, b as ReplyTelemetry, d as DispatchOutcome, i as Bus, j as VerifyWebhooks, k as RegisteredCount, o as SubscriberRegistration, s as busLoggerOf, u as DefaultSubscriptions, w as checkAckLegality, x as reportedWrite, z as MiddlewareMetadataKey } from "./phases-C5Steaa2.mjs";
2
+ import { $ as CacheFor, A as serializeReply, B as contextMenuRouteOf, C as Gate, F as ContextMenuNamesBrand, G as CommandMeta, H as selectMenuRouteOf, I as SlashRouteBrand, J as IsNever, L as RoutableConstructor, M as ComponentDefsBrand, N as ComponentKindBrand, P as ContextMenuKindBrand, U as storeComponentRoute, V as interactionRoutesOf, W as storeInteractionRoute, Y as BuilderComponent, _ as pickNotice, c as FocusedField, ct as NamesFor, et as OptionKind, i as AutocompletableNames, it as SlashRouteEntry, j as AutocompleteRouteBrand, k as SerializedReply, m as PermissionNames, n as PageCursor, nt as SlashOption, o as ChoiceValueOf, ot as MenuCacheFor, q as Promisable, r as pageCursor, rt as SlashRegistry, s as EntryFor, t as PAGE_MAX, tt as RouteCache, v as GateFitsWith, w as GateContextBase, z as areRoutes } from "./cursor-CO_MTgdZ.mjs";
2
3
  import { n as CommandBuilder, r as DeployResult } from "./basic-Dng__Ena.mjs";
3
- import { A as RegisteredCount, B as MiddlewareMetadataKey, C as AckState, D as AckTrace, E as sendTarget, F as EventMetadataKey, H as WebhookUrlMetadataKey, I as GatedMetadataKey, L as InteractionMetadataKey, M as VerifyWebhooks, N as PublishDefault, O as RegisterDefaults, P as CommandMetadataKey, R as InteractionRouteKeys, S as reportedWrite, T as checkAckLegality, V as SubscribeMetadataKey, a as StoredSubscriberCtor, b as Notice, d as DispatchOutcome, i as Bus, j as UnregisterSubscriber, k as RegisterSubscriber, o as SubscriberRegistration, s as busLoggerOf, u as DefaultSubscriptions, w as ReplyMethod, x as ReplyTelemetry, z as InteractionRoutes } from "./phases-F8yvPd60.mjs";
4
- import { a as PluginCtor, i as PluginArgs, n as Initializeable } from "./Plugin-CG9pWbPF.mjs";
4
+ import { a as PluginCtor, i as PluginArgs, n as Initializeable } from "./Plugin-BW2JH2_h.mjs";
5
5
  import { n as contextMenuLeaves, t as ContextMenuLeaves } from "./contextMenuLeaves-COzDYa6c.mjs";
6
6
  import "reflect-metadata";
7
+ import { AnyCustomId, DecodedParams } from "@seedcord/custom-id";
7
8
  import { ContextMenuCommandBuilder, SlashCommandBuilder } from "@discordjs/builders";
8
- import { SeedcordErrorCode } from "@seedcord/errors";
9
9
  import { ChannelType } from "discord-api-types/v10";
10
+ import { SeedcordErrorCode } from "@seedcord/errors";
10
11
  import { SeedcordError } from "@seedcord/errors/internal";
11
12
  import { DevChannel, SeedcordCliEvents, SeedcordFrameworkEvents } from "@seedcord/types/internal";
12
13
  import { BotColor, DeferOpts, EpochMs, HmrAware, ReplyResponse, SendOpts } from "@seedcord/types";
@@ -267,5 +268,5 @@ interface DispatchReport {
267
268
  declare function queuedMsFor(interactionId: string): number;
268
269
  declare function reportDispatch(bus: Bus, report: DispatchReport): void;
269
270
  //#endregion
270
- export { type AckState, AckTrace, type AnyCustomId, type AutocompletableNames, AutocompleteRouteBrand, type CacheFor, type ChoiceValueOf, type CommandBuilder, type CommandCtor, type CommandMeta, CommandMetadataKey, ComponentDefsBrand, ComponentDefsKey, ComponentKindBrand, ContextMenuKindBrand, type ContextMenuLeaves, ContextMenuNamesBrand, type DecodedComponentRoute, type DecodedParams, type DefaultSubscriptions, type DeployResult, type EntryFor, EventMetadataKey, type FocusedField, type GateFitsWith, GateNotice, type GateObserver, GatedMetadataKey, type HasComponentDefs, HasDangerousPermissions, HmrManager, type Initializeable, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, type MatchArms, type MenuCacheFor, MiddlewareMetadataKey, MissingPermissions, MissingRole, type NamesFor, NeedsAny, NotAllowed, NotInDm, NotInGuild, NotOwner, NoticeCard, OnCooldown, type OptionKind, type OptionLens, PAGE_MAX, type PageCursor, PermissionNames, type PluginArgs, type PluginCtor, PublishDefault, RegisterDefaults, RegisterSubscriber, RegisteredCount, type ReplyMethod, type ReplyTelemetry, ReportThrottle, type RoutableConstructor, type RouteCache, type SerializedReply, type SingleParams, type SlashOption, type SlashOptions, SlashRouteBrand, type SlashRouteEntry, type SlowGateMonitor, type StoredSubscriberCtor, SubscribeMetadataKey, type SubscriberRegistration, UnregisterSubscriber, VerifyWebhooks, WebhookUrlMetadataKey, accessorStore, areRoutes, asError, busLoggerOf, checkAckLegality, clearStore, contextMenuLeaves, contextMenuRouteOf, decodeComponentRoute, decodeFor, deferFlags, getDevChannel, guardedAccessor, interactionRoutesOf, isCommandClass, isEmojiTuple, outcomeFor, pageCursor, pickNotice, prefixOf, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runGates, runHandlerGates, selectMenuRouteOf, sendFlags, sendTarget, serializeReply, setBotColor, setDevChannel, slashRouteLeaves, slowGateMonitor, storeComponentRoute, storeInteractionRoute, translateSerializationError, wrapHot };
271
+ export { type AckState, AckTrace, type AutocompletableNames, AutocompleteRouteBrand, type CacheFor, type ChoiceValueOf, type CommandBuilder, type CommandCtor, type CommandMeta, CommandMetadataKey, ComponentDefsBrand, ComponentDefsKey, ComponentKindBrand, ContextMenuKindBrand, type ContextMenuLeaves, ContextMenuNamesBrand, type DecodedComponentRoute, type DefaultSubscriptions, type DeployResult, type EntryFor, EventMetadataKey, type FocusedField, type GateFitsWith, GateNotice, type GateObserver, GatedMetadataKey, type HasComponentDefs, HasDangerousPermissions, HmrManager, type Initializeable, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, type MatchArms, type MenuCacheFor, MiddlewareMetadataKey, MissingPermissions, MissingRole, type NamesFor, NeedsAny, NotAllowed, NotInDm, NotInGuild, NotOwner, NoticeCard, OnCooldown, type OptionKind, type OptionLens, PAGE_MAX, type PageCursor, PermissionNames, type PluginArgs, type PluginCtor, PublishDefault, RegisterDefaults, RegisterSubscriber, RegisteredCount, type ReplyMethod, type ReplyTelemetry, ReportThrottle, type RoutableConstructor, type RouteCache, type SerializedReply, type SingleParams, type SlashOption, type SlashOptions, SlashRouteBrand, type SlashRouteEntry, type SlowGateMonitor, type StoredSubscriberCtor, SubscribeMetadataKey, type SubscriberRegistration, UnregisterSubscriber, VerifyWebhooks, WebhookUrlMetadataKey, accessorStore, areRoutes, asError, busLoggerOf, checkAckLegality, clearStore, contextMenuLeaves, contextMenuRouteOf, decodeComponentRoute, deferFlags, getDevChannel, guardedAccessor, interactionRoutesOf, isCommandClass, isEmojiTuple, outcomeFor, pageCursor, pickNotice, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runGates, runHandlerGates, selectMenuRouteOf, sendFlags, sendTarget, serializeReply, setBotColor, setDevChannel, slashRouteLeaves, slowGateMonitor, storeComponentRoute, storeInteractionRoute, translateSerializationError, wrapHot };
271
272
  //# sourceMappingURL=internal.index.d.mts.map
@@ -1,8 +1,8 @@
1
- import { A as clearStore, C as InteractionMetadataKey, D as SubscribeMetadataKey, E as MiddlewareMetadataKey, M as contextMenuLeaves, O as WebhookUrlMetadataKey, S as GatedMetadataKey, T as InteractionRoutes, a as RegisterSubscriber, b as CommandMetadataKey, c as VerifyWebhooks, h as sendFlags, i as RegisterDefaults, j as guardedAccessor, k as accessorStore, m as deferFlags, n as busLoggerOf, o as RegisteredCount, p as ReportThrottle, s as UnregisterSubscriber, w as InteractionRouteKeys, x as EventMetadataKey, y as setBotColor } from "./Bus-BVwmKc-A.mjs";
2
- import { A as translateSerializationError, B as interactionRoutesOf, C as NotInDm, E as OnCooldown, F as checkAckLegality, G as decodeComponentRoute, H as storeComponentRoute, I as sendTarget, J as prefixOf, N as reportedWrite, P as AckTrace, R as areRoutes, S as NotAllowed, T as NotOwner, U as storeInteractionRoute, V as selectMenuRouteOf, W as ComponentDefsKey, X as Notice, Y as NoticeCard, _ as GateNotice, b as MissingRole, d as pickNotice, f as discardCommits, g as runCommits, h as runCheck, k as serializeReply, n as pageCursor, q as decodeFor, r as Silence, s as PermissionNames, t as PAGE_MAX, v as HasDangerousPermissions, w as NotInGuild, x as NeedsAny, y as MissingPermissions, z as contextMenuRouteOf } from "./cursor-GBUYz3jk.mjs";
1
+ import { A as translateSerializationError, B as interactionRoutesOf, C as NotInDm, E as OnCooldown, F as checkAckLegality, G as decodeComponentRoute, H as storeComponentRoute, I as sendTarget, K as NoticeCard, N as reportedWrite, P as AckTrace, R as areRoutes, S as NotAllowed, T as NotOwner, U as storeInteractionRoute, V as selectMenuRouteOf, W as ComponentDefsKey, _ as GateNotice, b as MissingRole, d as pickNotice, f as discardCommits, g as runCommits, h as runCheck, k as serializeReply, n as pageCursor, q as Notice, r as Silence, s as PermissionNames, t as PAGE_MAX, v as HasDangerousPermissions, w as NotInGuild, x as NeedsAny, y as MissingPermissions, z as contextMenuRouteOf } from "./cursor-CaT051ii.mjs";
2
+ import { C as SubscribeMetadataKey, D as guardedAccessor, E as clearStore, M as setBotColor, O as contextMenuLeaves, S as MiddlewareMetadataKey, T as accessorStore, _ as EventMetadataKey, a as RegisterSubscriber, b as InteractionRouteKeys, c as VerifyWebhooks, g as CommandMetadataKey, h as sendFlags, i as RegisterDefaults, m as deferFlags, n as busLoggerOf, o as RegisteredCount, p as ReportThrottle, s as UnregisterSubscriber, v as GatedMetadataKey, w as WebhookUrlMetadataKey, x as InteractionRoutes, y as InteractionMetadataKey } from "./Bus-yJGE6Fs2.mjs";
3
3
  import { n as asError, t as PublishDefault } from "./publishDefault-D826XXDQ.mjs";
4
4
  import { n as setDevChannel, t as getDevChannel } from "./devChannel-CQU7hq7Q.mjs";
5
- import { n as isCommandClass, t as slashRouteLeaves } from "./slashRouteLeaves-CbYRwqMY.mjs";
5
+ import { n as isCommandClass, t as slashRouteLeaves } from "./slashRouteLeaves-BQmbFm-S.mjs";
6
6
  import "reflect-metadata";
7
7
  import { paint } from "@seedcord/errors";
8
8
  import { Logger } from "@seedcord/logger";
@@ -170,5 +170,5 @@ function reportDispatch(bus, report) {
170
170
  }
171
171
 
172
172
  //#endregion
173
- export { AckTrace, AutocompleteRouteBrand, CommandMetadataKey, ComponentDefsBrand, ComponentDefsKey, ComponentKindBrand, ContextMenuKindBrand, ContextMenuNamesBrand, EventMetadataKey, GateNotice, GatedMetadataKey, HasDangerousPermissions, HmrManager, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, MiddlewareMetadataKey, MissingPermissions, MissingRole, NeedsAny, NotAllowed, NotInDm, NotInGuild, NotOwner, NoticeCard, OnCooldown, PAGE_MAX, PermissionNames, PublishDefault, RegisterDefaults, RegisterSubscriber, RegisteredCount, ReportThrottle, SlashRouteBrand, SubscribeMetadataKey, UnregisterSubscriber, VerifyWebhooks, WebhookUrlMetadataKey, accessorStore, areRoutes, asError, busLoggerOf, checkAckLegality, clearStore, contextMenuLeaves, contextMenuRouteOf, decodeComponentRoute, decodeFor, deferFlags, getDevChannel, guardedAccessor, interactionRoutesOf, isCommandClass, isEmojiTuple, outcomeFor, pageCursor, pickNotice, prefixOf, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runGates, runHandlerGates, selectMenuRouteOf, sendFlags, sendTarget, serializeReply, setBotColor, setDevChannel, slashRouteLeaves, slowGateMonitor, storeComponentRoute, storeInteractionRoute, translateSerializationError, wrapHot };
173
+ export { AckTrace, AutocompleteRouteBrand, CommandMetadataKey, ComponentDefsBrand, ComponentDefsKey, ComponentKindBrand, ContextMenuKindBrand, ContextMenuNamesBrand, EventMetadataKey, GateNotice, GatedMetadataKey, HasDangerousPermissions, HmrManager, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, MiddlewareMetadataKey, MissingPermissions, MissingRole, NeedsAny, NotAllowed, NotInDm, NotInGuild, NotOwner, NoticeCard, OnCooldown, PAGE_MAX, PermissionNames, PublishDefault, RegisterDefaults, RegisterSubscriber, RegisteredCount, ReportThrottle, SlashRouteBrand, SubscribeMetadataKey, UnregisterSubscriber, VerifyWebhooks, WebhookUrlMetadataKey, accessorStore, areRoutes, asError, busLoggerOf, checkAckLegality, clearStore, contextMenuLeaves, contextMenuRouteOf, decodeComponentRoute, deferFlags, getDevChannel, guardedAccessor, interactionRoutesOf, isCommandClass, isEmojiTuple, outcomeFor, pageCursor, pickNotice, queuedMsFor, reportDispatch, reportedWrite, routeIdOf, runGates, runHandlerGates, selectMenuRouteOf, sendFlags, sendTarget, serializeReply, setBotColor, setDevChannel, slashRouteLeaves, slowGateMonitor, storeComponentRoute, storeInteractionRoute, translateSerializationError, wrapHot };
174
174
  //# sourceMappingURL=internal.index.mjs.map
@@ -1,9 +1,9 @@
1
+ import { i as Bus, n as StartupPhase, r as CoreBase, t as ShutdownPhase } from "./phases-C5Steaa2.mjs";
1
2
  import { n as CommandBuilder, r as DeployResult } from "./basic-Dng__Ena.mjs";
2
- import { i as Bus, n as StartupPhase, r as CoreBase, t as ShutdownPhase } from "./phases-F8yvPd60.mjs";
3
- import "./index-ZzdQafFv.mjs";
4
- import { n as Initializeable } from "./Plugin-CG9pWbPF.mjs";
3
+ import "./index-CvneCObW.mjs";
4
+ import { n as Initializeable } from "./Plugin-BW2JH2_h.mjs";
5
5
  import { t as ContextMenuLeaves } from "./contextMenuLeaves-COzDYa6c.mjs";
6
- import { a as LifecycleTask, i as CoordinatedShutdown, n as shutdownOf } from "./Pluggable-DFNUIlJM.mjs";
6
+ import { a as LifecycleTask, i as CoordinatedShutdown, n as shutdownOf } from "./Pluggable-bFCmT4oB.mjs";
7
7
  import { Logger } from "@seedcord/logger";
8
8
  import { IncomingMessage, ServerResponse } from "node:http";
9
9
  import { HealthCheckConfig, HealthCheckOption, HmrAware, HmrUpdateEvent } from "@seedcord/types";
@@ -1,16 +1,16 @@
1
- import { D as SubscribeMetadataKey, M as contextMenuLeaves, a as RegisterSubscriber, b as CommandMetadataKey, c as VerifyWebhooks, f as Subscriber, i as RegisterDefaults, n as busLoggerOf, o as RegisteredCount, r as registrationFor, s as UnregisterSubscriber } from "./Bus-BVwmKc-A.mjs";
2
- import { t as CommandInjector } from "./subscribers-CGGQkUfM.mjs";
1
+ import { C as SubscribeMetadataKey, O as contextMenuLeaves, a as RegisterSubscriber, c as VerifyWebhooks, f as Subscriber, g as CommandMetadataKey, i as RegisterDefaults, n as busLoggerOf, o as RegisteredCount, r as registrationFor, s as UnregisterSubscriber } from "./Bus-yJGE6Fs2.mjs";
2
+ import { t as CommandInjector } from "./subscribers-DVa-Pr45.mjs";
3
3
  import { t as PublishDefault } from "./publishDefault-D826XXDQ.mjs";
4
4
  import { n as StartupPhase, t as ShutdownPhase } from "./phases-BauKJOTT.mjs";
5
5
  import { t as getDevChannel } from "./devChannel-CQU7hq7Q.mjs";
6
- import { n as isCommandClass, t as slashRouteLeaves } from "./slashRouteLeaves-CbYRwqMY.mjs";
6
+ import { n as isCommandClass, t as slashRouteLeaves } from "./slashRouteLeaves-BQmbFm-S.mjs";
7
7
  import { t as HmrModuleHandler } from "./HmrModuleHandler-9AUfKXRl.mjs";
8
- import { i as settleWithin, n as shutdownOf, r as assertNodeVersion } from "./Pluggable-Cf5-WWmW.mjs";
8
+ import { i as settleWithin, n as shutdownOf, r as assertNodeVersion } from "./Pluggable-BI_LQuPm.mjs";
9
9
  import { SlashCommandBuilder } from "@discordjs/builders";
10
- import { SeedcordErrorCode, paint } from "@seedcord/errors";
11
- import { Logger } from "@seedcord/logger";
12
10
  import { Routes } from "discord-api-types/v10";
11
+ import { SeedcordErrorCode, paint } from "@seedcord/errors";
13
12
  import { SeedcordError } from "@seedcord/errors/internal";
13
+ import { Logger } from "@seedcord/logger";
14
14
  import { formatFilePath } from "@seedcord/utils";
15
15
  import { Envapter } from "envapt";
16
16
  import { resolve } from "node:path";
@@ -1,2 +1,2 @@
1
- import { i as CoordinatedShutdown, r as CoordinatedStartup, t as Pluggable } from "./Pluggable-DFNUIlJM.mjs";
1
+ import { i as CoordinatedShutdown, r as CoordinatedStartup, t as Pluggable } from "./Pluggable-bFCmT4oB.mjs";
2
2
  export { CoordinatedShutdown, CoordinatedStartup, Pluggable };
@@ -1,8 +1,8 @@
1
1
  import { n as StartupPhase, t as ShutdownPhase } from "./phases-BauKJOTT.mjs";
2
- import { a as withTimeout, t as Pluggable } from "./Pluggable-Cf5-WWmW.mjs";
2
+ import { a as withTimeout, t as Pluggable } from "./Pluggable-BI_LQuPm.mjs";
3
3
  import { SeedcordErrorCode, paint } from "@seedcord/errors";
4
- import { Logger } from "@seedcord/logger";
5
4
  import { SeedcordAggregateError, SeedcordError, SeedcordTypeError } from "@seedcord/errors/internal";
5
+ import { Logger } from "@seedcord/logger";
6
6
 
7
7
  //#region src/node/Lifecycle/CoordinatedLifecycle.ts
8
8
  var CoordinatedLifecycle = class {
@@ -1,62 +1,9 @@
1
- import { Logger } from "@seedcord/logger";
2
1
  import { APIApplicationCommand } from "discord-api-types/v10";
2
+ import { Logger } from "@seedcord/logger";
3
3
  import { TypedEventEmitter } from "@seedcord/event-emitter";
4
4
  import { REST } from "@discordjs/rest";
5
5
  import { UUID } from "node:crypto";
6
6
  import { Config, EventFrequency, IRateLimiter, RenderContext, ReplyResponse, TypedExclude } from "@seedcord/types";
7
- //#region src/metadataKeys.d.ts
8
- declare enum InteractionRoutes {
9
- Slash = "slash",
10
- Button = "button",
11
- Modal = "modal",
12
- StringMenu = "stringMenu",
13
- UserMenu = "userMenu",
14
- RoleMenu = "roleMenu",
15
- ChannelMenu = "channelMenu",
16
- MentionableMenu = "mentionableMenu",
17
- MessageContextMenu = "messageContextMenu",
18
- UserContextMenu = "userContextMenu",
19
- Autocomplete = "autocomplete"
20
- }
21
- declare const InteractionMetadataKey: unique symbol;
22
- declare const InteractionRouteKeys: Record<InteractionRoutes, symbol>;
23
- declare const MiddlewareMetadataKey: unique symbol;
24
- declare const EventMetadataKey: unique symbol;
25
- declare const CommandMetadataKey: unique symbol;
26
- declare const GatedMetadataKey: unique symbol;
27
- declare const SubscribeMetadataKey: unique symbol;
28
- declare const WebhookUrlMetadataKey: unique symbol;
29
- //#endregion
30
- //#region src/subscribers/publishDefault.d.ts
31
- /** @internal PublishableKey excludes this key so publish() never emits it externally. */
32
- declare const PublishDefault: unique symbol;
33
- //#endregion
34
- //#region src/subscribers/slots.d.ts
35
- declare const RegisterDefaults: unique symbol;
36
- declare const VerifyWebhooks: unique symbol;
37
- declare const RegisteredCount: unique symbol;
38
- declare const RegisterSubscriber: unique symbol;
39
- declare const UnregisterSubscriber: unique symbol;
40
- //#endregion
41
- //#region src/reply/AckTrace.d.ts
42
- declare class AckTrace extends Error {
43
- constructor(method: ReplyMethod);
44
- }
45
- //#endregion
46
- //#region src/reply/ackLegality.d.ts
47
- type AckState = 'unacked' | 'deferred-reply' | 'deferred-update' | 'replied';
48
- type ReplyMethod = 'reply' | 'defer' | 'deferUpdate' | 'update' | 'followUp' | 'edit' | 'delete' | 'send' | 'showModal';
49
- declare function checkAckLegality(method: ReplyMethod, state: AckState, routeId: string, ackedBy?: AckTrace): void;
50
- declare function sendTarget(state: AckState): 'reply' | 'edit' | 'followUp';
51
- //#endregion
52
- //#region src/reply/responseReport.d.ts
53
- interface ReplyTelemetry {
54
- readonly bus: Bus;
55
- readonly interactionId: string;
56
- }
57
- type WriteMethod = ReplyMethod | 'respond';
58
- declare function reportedWrite<Result>(telemetry: ReplyTelemetry, routeId: string, method: WriteMethod, write: () => Promise<Result>): Promise<Result>;
59
- //#endregion
60
7
  //#region src/stops/Notice.d.ts
61
8
  /**
62
9
  * Base class for a user-facing refusal or a reported fault.
@@ -124,6 +71,59 @@ declare abstract class Notice extends Error {
124
71
  abstract render(ctx: RenderContext): ReplyResponse;
125
72
  }
126
73
  //#endregion
74
+ //#region src/metadataKeys.d.ts
75
+ declare enum InteractionRoutes {
76
+ Slash = "slash",
77
+ Button = "button",
78
+ Modal = "modal",
79
+ StringMenu = "stringMenu",
80
+ UserMenu = "userMenu",
81
+ RoleMenu = "roleMenu",
82
+ ChannelMenu = "channelMenu",
83
+ MentionableMenu = "mentionableMenu",
84
+ MessageContextMenu = "messageContextMenu",
85
+ UserContextMenu = "userContextMenu",
86
+ Autocomplete = "autocomplete"
87
+ }
88
+ declare const InteractionMetadataKey: unique symbol;
89
+ declare const InteractionRouteKeys: Record<InteractionRoutes, symbol>;
90
+ declare const MiddlewareMetadataKey: unique symbol;
91
+ declare const EventMetadataKey: unique symbol;
92
+ declare const CommandMetadataKey: unique symbol;
93
+ declare const GatedMetadataKey: unique symbol;
94
+ declare const SubscribeMetadataKey: unique symbol;
95
+ declare const WebhookUrlMetadataKey: unique symbol;
96
+ //#endregion
97
+ //#region src/subscribers/publishDefault.d.ts
98
+ /** @internal PublishableKey excludes this key so publish() never emits it externally. */
99
+ declare const PublishDefault: unique symbol;
100
+ //#endregion
101
+ //#region src/subscribers/slots.d.ts
102
+ declare const RegisterDefaults: unique symbol;
103
+ declare const VerifyWebhooks: unique symbol;
104
+ declare const RegisteredCount: unique symbol;
105
+ declare const RegisterSubscriber: unique symbol;
106
+ declare const UnregisterSubscriber: unique symbol;
107
+ //#endregion
108
+ //#region src/reply/AckTrace.d.ts
109
+ declare class AckTrace extends Error {
110
+ constructor(method: ReplyMethod);
111
+ }
112
+ //#endregion
113
+ //#region src/reply/ackLegality.d.ts
114
+ type AckState = 'unacked' | 'deferred-reply' | 'deferred-update' | 'replied';
115
+ type ReplyMethod = 'reply' | 'defer' | 'deferUpdate' | 'update' | 'followUp' | 'edit' | 'delete' | 'send' | 'showModal';
116
+ declare function checkAckLegality(method: ReplyMethod, state: AckState, routeId: string, ackedBy?: AckTrace): void;
117
+ declare function sendTarget(state: AckState): 'reply' | 'edit' | 'followUp';
118
+ //#endregion
119
+ //#region src/reply/responseReport.d.ts
120
+ interface ReplyTelemetry {
121
+ readonly bus: Bus;
122
+ readonly interactionId: string;
123
+ }
124
+ type WriteMethod = ReplyMethod | 'respond';
125
+ declare function reportedWrite<Result>(telemetry: ReplyTelemetry, routeId: string, method: WriteMethod, write: () => Promise<Result>): Promise<Result>;
126
+ //#endregion
127
127
  //#region src/subscribers/types/Subscriptions.d.ts
128
128
  /**
129
129
  * How a dispatch finished. The thrown value's type sets this, wherever it was thrown. A `Silence` and a
@@ -456,5 +456,5 @@ declare enum ShutdownPhase {
456
456
  Logout = 4
457
457
  }
458
458
  //#endregion
459
- export { RegisteredCount as A, MiddlewareMetadataKey as B, AckState as C, AckTrace as D, sendTarget as E, EventMetadataKey as F, WebhookUrlMetadataKey as H, GatedMetadataKey as I, InteractionMetadataKey as L, VerifyWebhooks as M, PublishDefault as N, RegisterDefaults as O, CommandMetadataKey as P, InteractionRouteKeys as R, reportedWrite as S, checkAckLegality as T, SubscribeMetadataKey as V, SubscriptionData as _, StoredSubscriberCtor as a, Notice as b, Subscriber as c, DispatchOutcome as d, FaultSource as f, ResponseSent as g, ResponseOutcome as h, Bus as i, UnregisterSubscriber as j, RegisterSubscriber as k, AttemptedWrite as l, ResponseFailed as m, StartupPhase as n, SubscriberRegistration as o, ResponseAttempt as p, CoreBase as r, busLoggerOf as s, ShutdownPhase as t, DefaultSubscriptions as u, SubscriptionKey as v, ReplyMethod as w, ReplyTelemetry as x, Subscriptions as y, InteractionRoutes as z };
460
- //# sourceMappingURL=phases-F8yvPd60.d.mts.map
459
+ export { UnregisterSubscriber as A, SubscribeMetadataKey as B, ReplyMethod as C, RegisterDefaults as D, AckTrace as E, GatedMetadataKey as F, Notice as H, InteractionMetadataKey as I, InteractionRouteKeys as L, PublishDefault as M, CommandMetadataKey as N, RegisterSubscriber as O, EventMetadataKey as P, InteractionRoutes as R, AckState as S, sendTarget as T, WebhookUrlMetadataKey as V, SubscriptionData as _, StoredSubscriberCtor as a, ReplyTelemetry as b, Subscriber as c, DispatchOutcome as d, FaultSource as f, ResponseSent as g, ResponseOutcome as h, Bus as i, VerifyWebhooks as j, RegisteredCount as k, AttemptedWrite as l, ResponseFailed as m, StartupPhase as n, SubscriberRegistration as o, ResponseAttempt as p, CoreBase as r, busLoggerOf as s, ShutdownPhase as t, DefaultSubscriptions as u, SubscriptionKey as v, checkAckLegality as w, reportedWrite as x, Subscriptions as y, MiddlewareMetadataKey as z };
460
+ //# sourceMappingURL=phases-C5Steaa2.d.mts.map
@@ -1,3 +1,3 @@
1
- import { c as PluginOptions, p as PluginLifecycleSpec, r as Plugin } from "./Plugin-CG9pWbPF.mjs";
1
+ import { c as PluginOptions, p as PluginLifecycleSpec, r as Plugin } from "./Plugin-BW2JH2_h.mjs";
2
2
  import { HmrAware, HmrUpdateEvent } from "@seedcord/types";
3
3
  export { type HmrAware, type HmrUpdateEvent, Plugin, type PluginLifecycleSpec, type PluginOptions };
@@ -1,3 +1,3 @@
1
- import { t as Plugin } from "./Plugin-C6oMqWf8.mjs";
1
+ import { t as Plugin } from "./Plugin-B0SRHzMX.mjs";
2
2
 
3
3
  export { Plugin };
@@ -1,4 +1,4 @@
1
- import { b as CommandMetadataKey, v as isBuilderComponentClass } from "./Bus-BVwmKc-A.mjs";
1
+ import { g as CommandMetadataKey, j as isBuilderComponentClass } from "./Bus-yJGE6Fs2.mjs";
2
2
  import { SlashCommandBuilder } from "@discordjs/builders";
3
3
  import { routeLeavesOf } from "@seedcord/utils/internal";
4
4
 
@@ -28,4 +28,4 @@ function slashRouteLeaves(commands) {
28
28
 
29
29
  //#endregion
30
30
  export { isCommandClass as n, slashRouteLeaves as t };
31
- //# sourceMappingURL=slashRouteLeaves-CbYRwqMY.mjs.map
31
+ //# sourceMappingURL=slashRouteLeaves-BQmbFm-S.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"slashRouteLeaves-CbYRwqMY.mjs","names":[],"sources":["../src/commands/isCommandClass.ts","../src/commands/slashRouteLeaves.ts"],"sourcesContent":["import { isBuilderComponentClass } from '#components/Component';\nimport { CommandMetadataKey } from '#src/metadataKeys';\n\nimport type { BuilderComponent } from '#components/Component';\n\n/** @internal */\nexport type CommandCtor = new () => BuilderComponent<'command' | 'context_menu'>;\n\n// the cli's codegen scan reads this too\n/** @internal */\nexport function isCommandClass(value: unknown): value is CommandCtor {\n return isBuilderComponentClass(value) && Reflect.hasMetadata(CommandMetadataKey, value);\n}\n","import { SlashCommandBuilder } from '@discordjs/builders';\nimport { routeLeavesOf } from '@seedcord/utils/internal';\n\nimport type { ContextMenuCommandBuilder } from '@discordjs/builders';\n\n/**\n * dedupes route keys since the same builder appears once per guild.\n * these come from the same {@link routeLeavesOf} that `seedcord codegen` reads, so the boot-time\n * check compares against the generated registry's keys.\n *\n * @internal\n */\nexport function slashRouteLeaves(commands: Iterable<SlashCommandBuilder | ContextMenuCommandBuilder>): Set<string> {\n const leaves = new Set<string>();\n for (const command of commands) {\n if (!(command instanceof SlashCommandBuilder)) continue;\n for (const leaf of routeLeavesOf(command.toJSON())) leaves.add(leaf.route);\n }\n return leaves;\n}\n"],"mappings":";;;;;;AAUA,SAAgB,eAAe,OAAsC;CACjE,OAAO,wBAAwB,KAAK,KAAK,QAAQ,YAAY,oBAAoB,KAAK;AAC1F;;;;;;;;;;;ACAA,SAAgB,iBAAiB,UAAkF;CAC/G,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,WAAW,UAAU;EAC5B,IAAI,EAAE,mBAAmB,sBAAsB;EAC/C,KAAK,MAAM,QAAQ,cAAc,QAAQ,OAAO,CAAC,GAAG,OAAO,IAAI,KAAK,KAAK;CAC7E;CACA,OAAO;AACX"}
1
+ {"version":3,"file":"slashRouteLeaves-BQmbFm-S.mjs","names":[],"sources":["../src/commands/isCommandClass.ts","../src/commands/slashRouteLeaves.ts"],"sourcesContent":["import { isBuilderComponentClass } from '#components/Component';\nimport { CommandMetadataKey } from '#src/metadataKeys';\n\nimport type { BuilderComponent } from '#components/Component';\n\n/** @internal */\nexport type CommandCtor = new () => BuilderComponent<'command' | 'context_menu'>;\n\n// the cli's codegen scan reads this too\n/** @internal */\nexport function isCommandClass(value: unknown): value is CommandCtor {\n return isBuilderComponentClass(value) && Reflect.hasMetadata(CommandMetadataKey, value);\n}\n","import { SlashCommandBuilder } from '@discordjs/builders';\nimport { routeLeavesOf } from '@seedcord/utils/internal';\n\nimport type { ContextMenuCommandBuilder } from '@discordjs/builders';\n\n/**\n * dedupes route keys since the same builder appears once per guild.\n * these come from the same {@link routeLeavesOf} that `seedcord codegen` reads, so the boot-time\n * check compares against the generated registry's keys.\n *\n * @internal\n */\nexport function slashRouteLeaves(commands: Iterable<SlashCommandBuilder | ContextMenuCommandBuilder>): Set<string> {\n const leaves = new Set<string>();\n for (const command of commands) {\n if (!(command instanceof SlashCommandBuilder)) continue;\n for (const leaf of routeLeavesOf(command.toJSON())) leaves.add(leaf.route);\n }\n return leaves;\n}\n"],"mappings":";;;;;;AAUA,SAAgB,eAAe,OAAsC;CACjE,OAAO,wBAAwB,KAAK,KAAK,QAAQ,YAAY,oBAAoB,KAAK;AAC1F;;;;;;;;;;;ACAA,SAAgB,iBAAiB,UAAkF;CAC/G,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,WAAW,UAAU;EAC5B,IAAI,EAAE,mBAAmB,sBAAsB;EAC/C,KAAK,MAAM,QAAQ,cAAc,QAAQ,OAAO,CAAC,GAAG,OAAO,IAAI,KAAK,KAAK;CAC7E;CACA,OAAO;AACX"}
@@ -1,9 +1,9 @@
1
- import { A as clearStore, M as contextMenuLeaves, j as guardedAccessor, k as accessorStore } from "./Bus-BVwmKc-A.mjs";
1
+ import { D as guardedAccessor, E as clearStore, O as contextMenuLeaves, T as accessorStore } from "./Bus-yJGE6Fs2.mjs";
2
2
  import { SlashCommandBuilder } from "@discordjs/builders";
3
+ import { ApplicationCommandType } from "discord-api-types/v10";
3
4
  import { paint } from "@seedcord/errors";
4
5
  import { Logger } from "@seedcord/logger";
5
6
  import { routeLeavesOf } from "@seedcord/utils/internal";
6
- import { ApplicationCommandType } from "discord-api-types/v10";
7
7
 
8
8
  //#region src/commands/CommandInjector.ts
9
9
  const commandStorage = accessorStore();
@@ -136,4 +136,4 @@ var CommandInjector = class {
136
136
 
137
137
  //#endregion
138
138
  export { Commands as n, ContextMenus as r, CommandInjector as t };
139
- //# sourceMappingURL=subscribers-CGGQkUfM.mjs.map
139
+ //# sourceMappingURL=subscribers-DVa-Pr45.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers-CGGQkUfM.mjs","names":[],"sources":["../src/commands/CommandInjector.ts"],"sourcesContent":["import { SlashCommandBuilder } from '@discordjs/builders';\nimport { paint } from '@seedcord/errors';\nimport { Logger } from '@seedcord/logger';\nimport { routeLeavesOf } from '@seedcord/utils/internal';\nimport { ApplicationCommandType } from 'discord-api-types/v10';\n\nimport { contextMenuLeaves } from '#src/commands/contextMenuLeaves';\nimport { accessorStore, clearStore, guardedAccessor } from '#src/miscellaneous/guarded';\n\nimport type {\n ContextMenuKind,\n MessageContextMenuRegistry,\n UserContextMenuRegistry\n} from '#registries/ContextMenuRegistry';\nimport type { SlashRegistry } from '#registries/SlashRegistry';\nimport type { CommandBuilder, DeployResult } from '#src/commands/types';\nimport type { APIApplicationCommand, Snowflake } from 'discord-api-types/v10';\n\nconst commandStorage = accessorStore<CommandInfo>();\nconst userMenuStorage = accessorStore<ContextMenuInfo>();\nconst messageMenuStorage = accessorStore<ContextMenuInfo>();\n\n/** What {@link Commands} resolves to for one slash route. */\nexport interface CommandInfo {\n /** The clickable `</config set:id>` mention. A route whose id did not resolve falls back to `/config set`. */\n readonly mention: string;\n /** The deployed command id. Absent when the command deployed to two or more guilds. */\n readonly id?: string;\n /** The full route, e.g. `config/set`. */\n readonly route: string;\n /** The route's own description, taken from the subcommand for a nested route. */\n readonly description: string;\n}\n\n/** Each registered slash route mapped to its deployed command. */\nexport type InjectedCommandMap = {\n [K in keyof SlashRegistry]: CommandInfo;\n};\n\n/**\n * The bot's deployed slash commands, keyed by {@link SlashRegistry}. Filled by\n * {@link CommandInjector} after each deploy, and a read before that throws.\n *\n * @example\n * ```ts\n * import { Commands } from '@seedcord/gateway';\n *\n * await this.reply(`Try ${Commands['config/set'].mention}`);\n *\n * // a help listing\n * const lines = Object.values(Commands).map((c) => `${c.mention} ${c.description}`);\n * ```\n */\nexport const Commands = guardedAccessor('Commands', commandStorage) as InjectedCommandMap;\n\n/** What {@link ContextMenus} resolves to for one context-menu command. */\nexport interface ContextMenuInfo {\n /** The deployed command id. Absent when the command deployed to two or more guilds. */\n readonly id?: string;\n /** The name shown in Discord's right-click menu. */\n readonly name: string;\n readonly kind: ContextMenuKind;\n}\n\n/** Deployed context-menu commands, split by kind because Discord scopes name uniqueness per command type. */\nexport interface InjectedContextMenuMap {\n readonly user: { [K in keyof UserContextMenuRegistry]: ContextMenuInfo };\n readonly message: { [K in keyof MessageContextMenuRegistry]: ContextMenuInfo };\n}\n\n/**\n * The bot's deployed context-menu commands. Filled by {@link CommandInjector} after each deploy, and a read\n * before that throws.\n *\n * @example\n * ```ts\n * import { ContextMenus } from '@seedcord/gateway';\n *\n * const id = ContextMenus.user['View Profile'].id;\n * ```\n */\nexport const ContextMenus = {\n user: guardedAccessor('ContextMenus.user', userMenuStorage),\n message: guardedAccessor('ContextMenus.message', messageMenuStorage)\n} as InjectedContextMenuMap;\n\nconst MULTI_GUILD = Symbol('seedcord:commands:multi-guild');\n\n// Discord scopes name uniqueness per type, and a context-menu name may be all lowercase like a slash name\nfunction commandKey(type: ApplicationCommandType, name: string): string {\n return `${type}:${name}`;\n}\n\nfunction slashBuildersOf(all: readonly CommandBuilder[]): SlashCommandBuilder[] {\n const slash = all.filter((command): command is SlashCommandBuilder => command instanceof SlashCommandBuilder);\n // a guild command in N guilds is the same builder pushed once per guild\n return [...new Set(slash)];\n}\n\ninterface DeployedIds {\n readonly global: Map<string, Snowflake>;\n readonly guild: Map<string, Snowflake | typeof MULTI_GUILD>;\n readonly warned: Set<string>;\n}\n\n/** @internal */\nexport class CommandInjector {\n private readonly logger = new Logger('Commands', { channel: 'bot' });\n\n public inject(deploy: DeployResult, all: readonly CommandBuilder[]): void {\n this.clear();\n\n const ids: DeployedIds = {\n global: this.indexByKey(deploy.global),\n guild: this.indexGuilds(deploy.guilds),\n warned: new Set<string>()\n };\n let clickable = 0;\n\n for (const command of slashBuildersOf(all)) {\n const id = this.resolveId(\n ApplicationCommandType.ChatInput,\n command.name,\n ids,\n 'falling back to plain text (not clickable)'\n );\n for (const leaf of routeLeavesOf(command.toJSON())) {\n commandStorage[leaf.route] = {\n mention: id ? this.toMention(leaf.route, id) : this.toPlain(leaf.route),\n ...(id && { id }),\n route: leaf.route,\n description: leaf.description\n };\n if (id) clickable++;\n }\n }\n\n const menus = contextMenuLeaves(all);\n this.injectMenus(menus.user, ApplicationCommandType.User, userMenuStorage, ids);\n this.injectMenus(menus.message, ApplicationCommandType.Message, messageMenuStorage, ids);\n\n this.logger.utils.summary('Linked commands', {\n clickable,\n plain: Object.keys(commandStorage).length - clickable,\n 'context menus': menus.user.size + menus.message.size\n });\n }\n\n private injectMenus(\n names: ReadonlySet<string>,\n kind: ContextMenuKind,\n storage: Record<string, ContextMenuInfo>,\n ids: DeployedIds\n ): void {\n for (const name of names) {\n const id = this.resolveId(kind, name, ids, 'leaving its id unset');\n storage[name] = { ...(id && { id }), name, kind };\n }\n }\n\n private indexByKey(collection: Map<Snowflake, APIApplicationCommand>): Map<string, Snowflake> {\n const map = new Map<string, Snowflake>();\n for (const command of collection.values()) map.set(commandKey(command.type, command.name), command.id);\n return map;\n }\n\n private indexGuilds(\n guilds: Map<Snowflake, Map<Snowflake, APIApplicationCommand>>\n ): Map<string, Snowflake | typeof MULTI_GUILD> {\n const map = new Map<string, Snowflake | typeof MULTI_GUILD>();\n for (const collection of guilds.values()) {\n for (const command of collection.values()) {\n const key = commandKey(command.type, command.name);\n const existing = map.get(key);\n // Discord assigns a separate id per guild, so two ids for one name means no single mention\n if (existing === undefined) map.set(key, command.id);\n else if (existing !== command.id) map.set(key, MULTI_GUILD);\n }\n }\n return map;\n }\n\n private resolveId(\n type: ApplicationCommandType,\n name: string,\n ids: DeployedIds,\n consequence: string\n ): Snowflake | undefined {\n const key = commandKey(type, name);\n const global = ids.global.get(key);\n if (global) return global;\n\n const guild = ids.guild.get(key);\n if (guild === undefined) return undefined;\n if (guild === MULTI_GUILD) {\n if (!ids.warned.has(key)) {\n this.logger.warn(`${paint.sky.bold(name)} is deployed to multiple guilds, ${consequence}.`);\n ids.warned.add(key);\n }\n return undefined;\n }\n return guild;\n }\n\n private toMention(route: string, id: Snowflake): string {\n return `</${route.replaceAll('/', ' ')}:${id}>`;\n }\n\n private toPlain(route: string): string {\n return `/${route.replaceAll('/', ' ')}`;\n }\n\n private clear(): void {\n for (const store of [commandStorage, userMenuStorage, messageMenuStorage]) clearStore(store);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"subscribers-DVa-Pr45.mjs","names":[],"sources":["../src/commands/CommandInjector.ts"],"sourcesContent":["import { SlashCommandBuilder } from '@discordjs/builders';\nimport { paint } from '@seedcord/errors';\nimport { Logger } from '@seedcord/logger';\nimport { routeLeavesOf } from '@seedcord/utils/internal';\nimport { ApplicationCommandType } from 'discord-api-types/v10';\n\nimport { contextMenuLeaves } from '#src/commands/contextMenuLeaves';\nimport { accessorStore, clearStore, guardedAccessor } from '#src/miscellaneous/guarded';\n\nimport type {\n ContextMenuKind,\n MessageContextMenuRegistry,\n UserContextMenuRegistry\n} from '#registries/ContextMenuRegistry';\nimport type { SlashRegistry } from '#registries/SlashRegistry';\nimport type { CommandBuilder, DeployResult } from '#src/commands/types';\nimport type { APIApplicationCommand, Snowflake } from 'discord-api-types/v10';\n\nconst commandStorage = accessorStore<CommandInfo>();\nconst userMenuStorage = accessorStore<ContextMenuInfo>();\nconst messageMenuStorage = accessorStore<ContextMenuInfo>();\n\n/** What {@link Commands} resolves to for one slash route. */\nexport interface CommandInfo {\n /** The clickable `</config set:id>` mention. A route whose id did not resolve falls back to `/config set`. */\n readonly mention: string;\n /** The deployed command id. Absent when the command deployed to two or more guilds. */\n readonly id?: string;\n /** The full route, e.g. `config/set`. */\n readonly route: string;\n /** The route's own description, taken from the subcommand for a nested route. */\n readonly description: string;\n}\n\n/** Each registered slash route mapped to its deployed command. */\nexport type InjectedCommandMap = {\n [K in keyof SlashRegistry]: CommandInfo;\n};\n\n/**\n * The bot's deployed slash commands, keyed by {@link SlashRegistry}. Filled by\n * {@link CommandInjector} after each deploy, and a read before that throws.\n *\n * @example\n * ```ts\n * import { Commands } from '@seedcord/gateway';\n *\n * await this.reply(`Try ${Commands['config/set'].mention}`);\n *\n * // a help listing\n * const lines = Object.values(Commands).map((c) => `${c.mention} ${c.description}`);\n * ```\n */\nexport const Commands = guardedAccessor('Commands', commandStorage) as InjectedCommandMap;\n\n/** What {@link ContextMenus} resolves to for one context-menu command. */\nexport interface ContextMenuInfo {\n /** The deployed command id. Absent when the command deployed to two or more guilds. */\n readonly id?: string;\n /** The name shown in Discord's right-click menu. */\n readonly name: string;\n readonly kind: ContextMenuKind;\n}\n\n/** Deployed context-menu commands, split by kind because Discord scopes name uniqueness per command type. */\nexport interface InjectedContextMenuMap {\n readonly user: { [K in keyof UserContextMenuRegistry]: ContextMenuInfo };\n readonly message: { [K in keyof MessageContextMenuRegistry]: ContextMenuInfo };\n}\n\n/**\n * The bot's deployed context-menu commands. Filled by {@link CommandInjector} after each deploy, and a read\n * before that throws.\n *\n * @example\n * ```ts\n * import { ContextMenus } from '@seedcord/gateway';\n *\n * const id = ContextMenus.user['View Profile'].id;\n * ```\n */\nexport const ContextMenus = {\n user: guardedAccessor('ContextMenus.user', userMenuStorage),\n message: guardedAccessor('ContextMenus.message', messageMenuStorage)\n} as InjectedContextMenuMap;\n\nconst MULTI_GUILD = Symbol('seedcord:commands:multi-guild');\n\n// Discord scopes name uniqueness per type, and a context-menu name may be all lowercase like a slash name\nfunction commandKey(type: ApplicationCommandType, name: string): string {\n return `${type}:${name}`;\n}\n\nfunction slashBuildersOf(all: readonly CommandBuilder[]): SlashCommandBuilder[] {\n const slash = all.filter((command): command is SlashCommandBuilder => command instanceof SlashCommandBuilder);\n // a guild command in N guilds is the same builder pushed once per guild\n return [...new Set(slash)];\n}\n\ninterface DeployedIds {\n readonly global: Map<string, Snowflake>;\n readonly guild: Map<string, Snowflake | typeof MULTI_GUILD>;\n readonly warned: Set<string>;\n}\n\n/** @internal */\nexport class CommandInjector {\n private readonly logger = new Logger('Commands', { channel: 'bot' });\n\n public inject(deploy: DeployResult, all: readonly CommandBuilder[]): void {\n this.clear();\n\n const ids: DeployedIds = {\n global: this.indexByKey(deploy.global),\n guild: this.indexGuilds(deploy.guilds),\n warned: new Set<string>()\n };\n let clickable = 0;\n\n for (const command of slashBuildersOf(all)) {\n const id = this.resolveId(\n ApplicationCommandType.ChatInput,\n command.name,\n ids,\n 'falling back to plain text (not clickable)'\n );\n for (const leaf of routeLeavesOf(command.toJSON())) {\n commandStorage[leaf.route] = {\n mention: id ? this.toMention(leaf.route, id) : this.toPlain(leaf.route),\n ...(id && { id }),\n route: leaf.route,\n description: leaf.description\n };\n if (id) clickable++;\n }\n }\n\n const menus = contextMenuLeaves(all);\n this.injectMenus(menus.user, ApplicationCommandType.User, userMenuStorage, ids);\n this.injectMenus(menus.message, ApplicationCommandType.Message, messageMenuStorage, ids);\n\n this.logger.utils.summary('Linked commands', {\n clickable,\n plain: Object.keys(commandStorage).length - clickable,\n 'context menus': menus.user.size + menus.message.size\n });\n }\n\n private injectMenus(\n names: ReadonlySet<string>,\n kind: ContextMenuKind,\n storage: Record<string, ContextMenuInfo>,\n ids: DeployedIds\n ): void {\n for (const name of names) {\n const id = this.resolveId(kind, name, ids, 'leaving its id unset');\n storage[name] = { ...(id && { id }), name, kind };\n }\n }\n\n private indexByKey(collection: Map<Snowflake, APIApplicationCommand>): Map<string, Snowflake> {\n const map = new Map<string, Snowflake>();\n for (const command of collection.values()) map.set(commandKey(command.type, command.name), command.id);\n return map;\n }\n\n private indexGuilds(\n guilds: Map<Snowflake, Map<Snowflake, APIApplicationCommand>>\n ): Map<string, Snowflake | typeof MULTI_GUILD> {\n const map = new Map<string, Snowflake | typeof MULTI_GUILD>();\n for (const collection of guilds.values()) {\n for (const command of collection.values()) {\n const key = commandKey(command.type, command.name);\n const existing = map.get(key);\n // Discord assigns a separate id per guild, so two ids for one name means no single mention\n if (existing === undefined) map.set(key, command.id);\n else if (existing !== command.id) map.set(key, MULTI_GUILD);\n }\n }\n return map;\n }\n\n private resolveId(\n type: ApplicationCommandType,\n name: string,\n ids: DeployedIds,\n consequence: string\n ): Snowflake | undefined {\n const key = commandKey(type, name);\n const global = ids.global.get(key);\n if (global) return global;\n\n const guild = ids.guild.get(key);\n if (guild === undefined) return undefined;\n if (guild === MULTI_GUILD) {\n if (!ids.warned.has(key)) {\n this.logger.warn(`${paint.sky.bold(name)} is deployed to multiple guilds, ${consequence}.`);\n ids.warned.add(key);\n }\n return undefined;\n }\n return guild;\n }\n\n private toMention(route: string, id: Snowflake): string {\n return `</${route.replaceAll('/', ' ')}:${id}>`;\n }\n\n private toPlain(route: string): string {\n return `/${route.replaceAll('/', ' ')}`;\n }\n\n private clear(): void {\n for (const store of [commandStorage, userMenuStorage, messageMenuStorage]) clearStore(store);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@seedcord/core",
3
3
  "type": "module",
4
- "version": "0.4.0",
4
+ "version": "0.4.1",
5
5
  "engines": {
6
6
  "node": ">=24.11"
7
7
  },
@@ -77,10 +77,11 @@
77
77
  "@discordjs/rest": "^2.6.3",
78
78
  "discord-api-types": "^0.38.52",
79
79
  "reflect-metadata": "^0.2.2",
80
- "@seedcord/errors": "^0.5.0",
80
+ "@seedcord/custom-id": "^0.1.0",
81
+ "@seedcord/errors": "^0.5.1",
81
82
  "@seedcord/event-emitter": "^0.1.5",
82
83
  "@seedcord/logger": "^0.2.2",
83
- "@seedcord/types": "^0.10.0",
84
+ "@seedcord/types": "^0.10.1",
84
85
  "@seedcord/utils": "^0.8.8"
85
86
  },
86
87
  "devDependencies": {
@@ -100,10 +101,10 @@
100
101
  "scripts": {
101
102
  "build": "tsdown",
102
103
  "clean": "rm -rf dist",
103
- "lint": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --cache",
104
- "lint:fix": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --fix --cache",
105
- "fmt": "prettier --write 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache",
106
- "fmt:check": "prettier --check 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache",
104
+ "lint": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --cache --no-error-on-unmatched-pattern",
105
+ "lint:fix": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --fix --cache --no-error-on-unmatched-pattern",
106
+ "fmt": "prettier --write 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache --no-error-on-unmatched-pattern",
107
+ "fmt:check": "prettier --check 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache --no-error-on-unmatched-pattern",
107
108
  "tc": "tsgo --noEmit",
108
109
  "test": "vitest run",
109
110
  "test:watch": "vitest dev",