@seedcord/core 0.1.0-next.0 → 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.
- package/dist/CustomId-BJF6mbJs.d.mts +317 -0
- package/dist/CustomId-CqiuEllp.cjs +759 -0
- package/dist/CustomId-CqiuEllp.cjs.map +1 -0
- package/dist/CustomId-XgZ2KDgT.mjs +712 -0
- package/dist/CustomId-XgZ2KDgT.mjs.map +1 -0
- package/dist/index.cjs +105 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +159 -1
- package/dist/index.mjs +100 -2
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.cjs +30 -0
- package/dist/internal.index.cjs.map +1 -0
- package/dist/internal.index.d.mts +83 -1
- package/dist/internal.index.mjs +23 -1
- package/dist/internal.index.mjs.map +1 -0
- package/package.json +9 -2
|
@@ -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
|