@seedcord/core 0.0.1 → 0.1.0-next.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.
@@ -0,0 +1,317 @@
1
+ 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";
2
+ import { Snowflake } from "discord-api-types/v10";
3
+
4
+ //#region src/components/builderTypes.d.ts
5
+ /**
6
+ * Available Discord.js builder classes for use with BuilderComponent for commands, embeds, modals, etc.
7
+ *
8
+ * @internal
9
+ */
10
+ declare const BuilderTypes: {
11
+ command: typeof SlashCommandBuilder;
12
+ context_menu: typeof ContextMenuCommandBuilder;
13
+ subcommand: typeof SlashCommandSubcommandBuilder;
14
+ group: typeof SlashCommandSubcommandGroupBuilder;
15
+ embed: typeof EmbedBuilder;
16
+ modal: typeof ModalBuilder;
17
+ label: typeof LabelBuilder;
18
+ text_input: typeof TextInputBuilder;
19
+ file_upload: typeof FileUploadBuilder;
20
+ checkbox: typeof CheckboxBuilder;
21
+ checkbox_group: typeof CheckboxGroupBuilder;
22
+ checkbox_group_option: typeof CheckboxGroupOptionBuilder;
23
+ radio_group: typeof RadioGroupBuilder;
24
+ radio_group_option: typeof RadioGroupOptionBuilder;
25
+ button: typeof ButtonBuilder;
26
+ menu_string: typeof StringSelectMenuBuilder;
27
+ menu_option_string: typeof StringSelectMenuOptionBuilder;
28
+ menu_user: typeof UserSelectMenuBuilder;
29
+ menu_channel: typeof ChannelSelectMenuBuilder;
30
+ menu_mentionable: typeof MentionableSelectMenuBuilder;
31
+ menu_role: typeof RoleSelectMenuBuilder;
32
+ container: typeof ContainerBuilder;
33
+ text_display: typeof TextDisplayBuilder;
34
+ file: typeof FileBuilder;
35
+ media: typeof MediaGalleryBuilder;
36
+ section: typeof SectionBuilder;
37
+ separator: typeof SeparatorBuilder;
38
+ };
39
+ /**
40
+ * Available Discord.js action row classes for use with RowComponent for Select Menus and Buttons
41
+ *
42
+ * @internal
43
+ */
44
+ declare const RowTypes: {
45
+ button: typeof ActionRowBuilder<ButtonBuilder>;
46
+ menu_string: typeof ActionRowBuilder<StringSelectMenuBuilder>;
47
+ menu_user: typeof ActionRowBuilder<UserSelectMenuBuilder>;
48
+ menu_channel: typeof ActionRowBuilder<ChannelSelectMenuBuilder>;
49
+ menu_mentionable: typeof ActionRowBuilder<MentionableSelectMenuBuilder>;
50
+ menu_role: typeof ActionRowBuilder<RoleSelectMenuBuilder>;
51
+ };
52
+ /**
53
+ * Available Discord.js builder types for use with BuilderComponent
54
+ */
55
+ type BuilderType = keyof typeof BuilderTypes;
56
+ /**
57
+ * @internal
58
+ */
59
+ type InstantiatedBuilder<BuilderKey extends BuilderType> = InstanceType<(typeof BuilderTypes)[BuilderKey]>;
60
+ /**
61
+ * Available Discord.js action row types for use with RowComponent
62
+ */
63
+ type RowType = keyof typeof RowTypes;
64
+ /**
65
+ * @internal
66
+ */
67
+ type InstantiatedActionRow<RowKey extends RowType> = InstanceType<(typeof RowTypes)[RowKey]>;
68
+ //#endregion
69
+ //#region src/components/Component.d.ts
70
+ /**
71
+ * Base class for Discord component wrappers.
72
+ *
73
+ * @typeParam TComponent - The Discord.js component type being wrapped
74
+ *
75
+ * @internal
76
+ */
77
+ declare abstract class BaseComponent<TComponent> {
78
+ private readonly _component;
79
+ protected constructor(ComponentClass: new () => TComponent);
80
+ /**
81
+ * Returns the live builder, ready to send in a Discord message or nest in another component.
82
+ *
83
+ * Configure it through `this.instance`. Reading this can apply the bot color (see
84
+ * {@link BuilderComponent}), so it has a side effect.
85
+ * @example new SomeComponent().component
86
+ */
87
+ abstract get component(): InstantiatedBuilder<BuilderType> | InstantiatedActionRow<RowType>;
88
+ /**
89
+ * The wrapped builder, for calling Discord.js methods like setTitle() and setDescription() inside a subclass.
90
+ *
91
+ * @example this.instance.setTitle('My Modal')
92
+ */
93
+ protected get instance(): TComponent;
94
+ }
95
+ /**
96
+ * Base class for Discord.js builder components
97
+ *
98
+ * Wraps Discord.js builders (SlashCommandBuilder, EmbedBuilder, etc.) with
99
+ * Seedcord-specific defaults and helper methods.
100
+ *
101
+ * @typeParam BuilderKey - The type of Discord.js builder being wrapped
102
+ */
103
+ declare abstract class BuilderComponent<BuilderKey extends BuilderType> extends BaseComponent<InstantiatedBuilder<BuilderKey>> {
104
+ readonly type: BuilderKey;
105
+ private colorApplied;
106
+ protected constructor(type: BuilderKey);
107
+ get component(): InstantiatedBuilder<BuilderKey>;
108
+ private applyBotColor;
109
+ }
110
+ /**
111
+ * Base class for Discord action row components
112
+ *
113
+ * Wraps Discord.js action row builder with Seedcord-specific defaults and helper methods.
114
+ *
115
+ * @typeParam RowKey - The Discord.js action row type being wrapped
116
+ */
117
+ declare abstract class RowComponent<RowKey extends RowType> extends BaseComponent<InstantiatedActionRow<RowKey>> {
118
+ readonly type: RowKey;
119
+ protected constructor(type: RowKey);
120
+ get component(): InstantiatedActionRow<RowKey>;
121
+ }
122
+ //#endregion
123
+ //#region src/customId/Field.d.ts
124
+ /**
125
+ * One field in a customId shape, its wire kind plus the type it decodes to.
126
+ *
127
+ * @internal
128
+ */
129
+ interface CustomIdField<Decoded> {
130
+ /** Which wire encoding this field uses. */
131
+ readonly kind: 'snowflake' | 'uuid' | 'int' | 'bool' | 'oneOf' | 'string';
132
+ /** Lower bound, for a bounded int field. */
133
+ readonly min?: number;
134
+ /** Upper bound, for a bounded int field. */
135
+ readonly max?: number;
136
+ /** The allowed values, for a oneOf field. */
137
+ readonly choices?: readonly string[];
138
+ /** Phantom only, carries the decoded type and is never set at runtime. */
139
+ readonly decoded?: Decoded;
140
+ }
141
+ /**
142
+ * The set of fields a customId carries, keyed by name.
143
+ *
144
+ * @internal
145
+ */
146
+ type CustomIdShape = Record<string, CustomIdField<unknown>>;
147
+ /**
148
+ * The decoded result, each field name mapped to its decoded type.
149
+ *
150
+ * @internal
151
+ */
152
+ type DecodedParams<Shape extends CustomIdShape> = { [Name in keyof Shape]: Shape[Name] extends CustomIdField<infer Decoded> ? Decoded : never };
153
+ //#endregion
154
+ //#region ../../node_modules/.pnpm/type-fest@5.7.0/node_modules/type-fest/source/non-empty-tuple.d.ts
155
+ /**
156
+ Matches any non-empty tuple.
157
+
158
+ @example
159
+ ```
160
+ import type {NonEmptyTuple} from 'type-fest';
161
+
162
+ const sum = (...numbers: NonEmptyTuple<number>) => numbers.reduce((total, value) => total + value, 0);
163
+
164
+ sum(1, 2, 3);
165
+ // Ok
166
+
167
+ // @ts-expect-error
168
+ sum();
169
+ // Error: Expected at least 1 arguments, but got 0.
170
+ ```
171
+
172
+ @see {@link RequireAtLeastOne} for objects
173
+
174
+ @category Array
175
+ */
176
+ type NonEmptyTuple<T = unknown> = readonly [T, ...T[]];
177
+ //#endregion
178
+ //#region src/customId/CustomId.d.ts
179
+ /** Strip the layout hash off the routeKey to recover the stable prefix the controller routes by. @internal */
180
+ declare function prefixOf(wire: string): string;
181
+ /**
182
+ * A typed customId. The single source of truth shared by the component that mints it and the handler
183
+ * that reads it. This gives you typed reads on the `.customId` field in components. Values are packed into a compact wire string rather than plain stringified tokens, so the 100-char Discord limit goes further. More string per string, basically.
184
+ *
185
+ * @typeParam Prefix - The stable route prefix, e.g. 'approve'.
186
+ * @typeParam Shape - The accumulated fields, filled in by the chain.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * const ApproveId = new CustomId('approve')
191
+ * .snowflake('userId')
192
+ * .oneOf('action', ['approve', 'deny']);
193
+ *
194
+ * // Set the custom id on a button when creating it.
195
+ * new ButtonBuilder().setCustomId(ApproveId.encode({ userId: '123', action: 'approve' }));
196
+ *
197
+ * // reading in the handler: userId comes back a string
198
+ * const { userId, action } = this.params; // userId: string, action: 'approve' | 'deny'
199
+ * await this.event.guild?.members.fetch(userId);
200
+ * ```
201
+ */
202
+ declare class CustomId<Prefix extends string, Shape extends CustomIdShape = {}> {
203
+ /** The stable route prefix, e.g. 'approve'. */
204
+ readonly prefix: Prefix;
205
+ /** Like a zod shape */
206
+ readonly shape: Shape;
207
+ /** The prefix plus a short hash of the shape, the part of the wire before the colon. */
208
+ readonly routeKey: string;
209
+ constructor(prefix: Prefix, shape?: Shape);
210
+ private add;
211
+ /**
212
+ * Add a Discord ID field, decoded as a string (the `Snowflake` type from discord-api-types).
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * new CustomId('ban').snowflake('userId');
217
+ * ```
218
+ */
219
+ snowflake<Name extends string>(name: Name): CustomId<Prefix, Shape & Record<Name, CustomIdField<Snowflake>>>;
220
+ /**
221
+ * Add a UUID field, decoded as a lowercase uuid string.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * new CustomId('ticket').uuid('ticketId');
226
+ * ```
227
+ */
228
+ uuid<Name extends string>(name: Name): CustomId<Prefix, Shape & Record<Name, CustomIdField<string>>>;
229
+ /**
230
+ * Add an integer field with no bounds, for a value up to 2^53.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * new CustomId('shop').int('amount');
235
+ * ```
236
+ */
237
+ int<Name extends string>(name: Name): CustomId<Prefix, Shape & Record<Name, CustomIdField<number>>>;
238
+ /**
239
+ * Add an integer field bounded by min and max, so it packs into fewer characters on the wire.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * new CustomId('paginate').int('page', 1, 50);
244
+ * ```
245
+ */
246
+ int<Name extends string>(name: Name, min: number, max: number): CustomId<Prefix, Shape & Record<Name, CustomIdField<number>>>;
247
+ /**
248
+ * Add a boolean flag.
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * new CustomId('settings').bool('silent');
253
+ * ```
254
+ */
255
+ bool<Name extends string>(name: Name): CustomId<Prefix, Shape & Record<Name, CustomIdField<boolean>>>;
256
+ /**
257
+ * Add a field that is one value from a fixed list, decoded as the literal union. No `as const` needed.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * new CustomId('poll').oneOf('choice', ['yes', 'no', 'abstain']);
262
+ * ```
263
+ */
264
+ oneOf<Name extends string, const Choices extends NonEmptyTuple<string>>(name: Name, choices: Choices): CustomId<Prefix, Shape & Record<Name, CustomIdField<Choices[number]>>>;
265
+ /**
266
+ * Add a free short text field. Avoid it where possible, it cannot be packed so it costs the most wire space.
267
+ *
268
+ * @example
269
+ * ```ts
270
+ * new CustomId('note').str('message');
271
+ * ```
272
+ */
273
+ str<Name extends string>(name: Name): CustomId<Prefix, Shape & Record<Name, CustomIdField<string>>>;
274
+ /**
275
+ * Mint a wire string from values. Throws if a value is out of its field's range or the wire is over 100 chars.
276
+ *
277
+ * @param values - One value per field, typed by the chain.
278
+ * @returns The wire string to put on the component's customId.
279
+ */
280
+ encode(values: DecodedParams<Shape>): string;
281
+ /**
282
+ * Read a wire string back into values.
283
+ *
284
+ * - This will refuse with a default Notice when the shape changed since the wire was minted.
285
+ * - Or refuse with a different default Notice on a corrupt or foreign wire.
286
+ *
287
+ * @param wire - The customId string from the interaction.
288
+ * @returns The decoded values, typed by the chain.
289
+ */
290
+ decode(wire: string): DecodedParams<Shape>;
291
+ /** True if this wire was minted from this customId's prefix, ignoring the shape hash. */
292
+ owns(wire: string): boolean;
293
+ }
294
+ /**
295
+ * Any customId, for places where the exact prefix and shape do not matter.
296
+ *
297
+ * @internal
298
+ */
299
+ type AnyCustomId = CustomId<string, CustomIdShape>;
300
+ /**
301
+ * The outcome of decoding a wire against several customIds, the matched prefix paired with its values.
302
+ *
303
+ * @internal
304
+ */
305
+ type DecodedRoute<Defs extends readonly AnyCustomId[]> = { [Index in keyof Defs]: Defs[Index] extends AnyCustomId ? {
306
+ readonly prefix: Defs[Index]['prefix'];
307
+ readonly params: DecodedParams<Defs[Index]['shape']>;
308
+ } : never }[number];
309
+ /**
310
+ * Find the customId whose prefix owns this wire, decode against it, and report which one matched.
311
+ *
312
+ * @internal
313
+ */
314
+ declare function decodeFor<Defs extends readonly AnyCustomId[]>(defs: Defs, wire: string): DecodedRoute<Defs>;
315
+ //#endregion
316
+ export { CustomIdField as a, RowComponent as c, prefixOf as i, BuilderType as l, CustomId as n, DecodedParams as o, decodeFor as r, BuilderComponent as s, AnyCustomId as t, RowType as u };
317
+ //# sourceMappingURL=CustomId-BJF6mbJs.d.mts.map