@seedcord/core 0.1.0-next.1 → 0.1.0-next.3
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--QizzBOn.d.mts +660 -0
- package/dist/{CustomId-CqiuEllp.cjs → CustomId-DV7daU7r.cjs} +321 -87
- package/dist/CustomId-DV7daU7r.cjs.map +1 -0
- package/dist/{CustomId-XgZ2KDgT.mjs → CustomId-epJayEGO.mjs} +196 -88
- package/dist/CustomId-epJayEGO.mjs.map +1 -0
- package/dist/index.cjs +347 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +230 -48
- package/dist/index.mjs +339 -6
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.cjs +50 -1
- package/dist/internal.index.cjs.map +1 -1
- package/dist/internal.index.d.mts +61 -41
- package/dist/internal.index.mjs +32 -2
- package/dist/internal.index.mjs.map +1 -1
- package/package.json +8 -4
- package/dist/CustomId-BJF6mbJs.d.mts +0 -317
- package/dist/CustomId-CqiuEllp.cjs.map +0 -1
- package/dist/CustomId-XgZ2KDgT.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { C as BuilderComponent, E as RowType, S as RegisterCommand, T as BuilderType, _ as RequiredOf, b as CoreBase, d as JoinNames, f as TwoOrMore, g as GateContextBase, h as Gate, m as EffectGate, n as CustomId, p as Notice, s as GateNoticeOptions, u as IntersectRequired, v as defineEffectGate, w as RowComponent, y as defineGate } from "./CustomId--QizzBOn.mjs";
|
|
2
|
+
import { ValidDuration } from "@seedcord/utils";
|
|
3
|
+
import { ChannelType } from "discord-api-types/v10";
|
|
4
|
+
import { EpochMs, RenderContext, ReplyResponse } from "@seedcord/types";
|
|
3
5
|
|
|
4
6
|
//#region src/registries/ContextMenuRegistry.d.ts
|
|
5
7
|
/**
|
|
6
8
|
* Maps each user context-menu command name to a presence marker. Populated by `seedcord codegen`, which
|
|
7
|
-
* reads every command's `toJSON()` and emits a `declare module 'seedcord'` augmentation, so
|
|
9
|
+
* reads every command's `toJSON()` and emits a `declare module '@seedcord/gateway'` augmentation, so
|
|
8
10
|
* `keyof UserContextMenuRegistry` is the compile-time union of every registered user context-menu name.
|
|
9
11
|
* Do not augment it by hand, run `seedcord codegen`.
|
|
10
12
|
*
|
|
@@ -14,7 +16,7 @@ import { RenderContext, ReplyResponse } from "@seedcord/types";
|
|
|
14
16
|
* @example
|
|
15
17
|
* ```ts
|
|
16
18
|
* // seedcord-gen.d.ts (emitted, committed)
|
|
17
|
-
* declare module 'seedcord' {
|
|
19
|
+
* declare module '@seedcord/gateway' {
|
|
18
20
|
* interface UserContextMenuRegistry {
|
|
19
21
|
* 'View Profile': true;
|
|
20
22
|
* }
|
|
@@ -32,7 +34,7 @@ interface UserContextMenuRegistry {}
|
|
|
32
34
|
interface MessageContextMenuRegistry {}
|
|
33
35
|
//#endregion
|
|
34
36
|
//#region src/registries/SlashOptionRegistry.d.ts
|
|
35
|
-
/** A slash option kind
|
|
37
|
+
/** A slash option kind as a plain string union (`string`, `channel`, ...), keyed to the registry. */
|
|
36
38
|
type OptionKind = 'string' | 'integer' | 'number' | 'boolean' | 'user' | 'channel' | 'role' | 'mentionable' | 'attachment';
|
|
37
39
|
/** The type-relevant shape of one slash option, as emitted by `seedcord codegen` into a registry row. */
|
|
38
40
|
interface SlashOption {
|
|
@@ -40,16 +42,17 @@ interface SlashOption {
|
|
|
40
42
|
required: boolean;
|
|
41
43
|
choices?: readonly (string | number)[];
|
|
42
44
|
autocomplete?: true;
|
|
45
|
+
channelTypes?: readonly ChannelType[];
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
48
|
* Maps each slash route string to its option table. Populated by `seedcord codegen`, which reads every
|
|
46
|
-
* command's `toJSON()` and emits a `declare module 'seedcord'` augmentation, so `keyof SlashOptionRegistry`
|
|
49
|
+
* command's `toJSON()` and emits a `declare module '@seedcord/gateway'` augmentation, so `keyof SlashOptionRegistry`
|
|
47
50
|
* is the compile-time union of every registered route. Do not augment it by hand, run `seedcord codegen`.
|
|
48
51
|
*
|
|
49
52
|
* @example
|
|
50
53
|
* ```ts
|
|
51
54
|
* // seedcord-gen.d.ts (emitted, committed)
|
|
52
|
-
* declare module 'seedcord' {
|
|
55
|
+
* declare module '@seedcord/gateway' {
|
|
53
56
|
* interface SlashOptionRegistry {
|
|
54
57
|
* ban: { target: { kind: 'user'; required: true }; reason: { kind: 'string'; required: false } };
|
|
55
58
|
* 'demo/setup': { channel: { kind: 'channel'; required: true } };
|
|
@@ -59,71 +62,250 @@ interface SlashOption {
|
|
|
59
62
|
*/
|
|
60
63
|
interface SlashOptionRegistry {}
|
|
61
64
|
//#endregion
|
|
62
|
-
//#region src/
|
|
65
|
+
//#region src/dispatch/DispatchContext.d.ts
|
|
63
66
|
/**
|
|
64
|
-
*
|
|
67
|
+
* The per-dispatch bag. Any code can merge fields into it by declaration merging, the
|
|
68
|
+
* same pattern as {@link SlashOptionRegistry}. It stays empty until one does, so `keyof DispatchState` is
|
|
69
|
+
* `never` and the bag is inert.
|
|
70
|
+
*/
|
|
71
|
+
interface DispatchState {}
|
|
72
|
+
/**
|
|
73
|
+
* A typed bag allocated once per interaction dispatch and handed to the handler. The middleware and i18n
|
|
74
|
+
* work reads and writes it through {@link DispatchState}. Today the bag is empty, so it only carries the
|
|
75
|
+
* dispatched `routeId`.
|
|
76
|
+
*/
|
|
77
|
+
declare class DispatchContext {
|
|
78
|
+
readonly routeId: string | null;
|
|
79
|
+
private readonly state;
|
|
80
|
+
constructor(routeId: string | null);
|
|
81
|
+
set<Key extends keyof DispatchState>(key: Key, value: DispatchState[Key]): void;
|
|
82
|
+
get<Key extends keyof DispatchState>(key: Key): DispatchState[Key] | undefined;
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/gates/combinators.d.ts
|
|
86
|
+
/**
|
|
87
|
+
* Runs each gate in order and refuses on the first refusal. Takes two or more arms. The required
|
|
88
|
+
* context is the intersection of the arms, so an event-only and an interaction-only gate cannot be
|
|
89
|
+
* combined.
|
|
65
90
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
91
|
+
* @typeParam Gates - The tuple of two or more gate arms, run left to right.
|
|
92
|
+
* @param gates - The gate arms to run in order, all refused on the first refusal.
|
|
93
|
+
*
|
|
94
|
+
* @see {@link or}
|
|
70
95
|
*
|
|
71
96
|
* @example
|
|
72
97
|
* ```ts
|
|
73
|
-
* import {
|
|
74
|
-
* import { TextDisplayBuilder } from '@discordjs/builders';
|
|
98
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
75
99
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* new TextDisplayBuilder().setContent(`### Insufficient balance\nYou need more than ${balance} coins.`)
|
|
82
|
-
* );
|
|
100
|
+
* \@Gated(and(GuildOnly(), RequirePermissions([PermissionFlagsBits.BanMembers])))
|
|
101
|
+
* \@SlashRoute('ban')
|
|
102
|
+
* class BanHandler extends SlashHandler<'ban'> {
|
|
103
|
+
* async execute() {
|
|
104
|
+
* // ...
|
|
83
105
|
* }
|
|
84
106
|
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
declare function and<Gates extends TwoOrMore<Gate<GateContextBase>>>(...gates: Gates): Gate<IntersectRequired<Gates> & GateContextBase, JoinNames<Gates, ' & '>>;
|
|
110
|
+
interface OrOptions {
|
|
111
|
+
fail: Notice | ((ctx: GateContextBase) => Notice);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Runs each gate in order and passes on the first arm that passes. Takes two or more arms. The
|
|
115
|
+
* required context is the union of the arms, so a handler that matches any one arm fits. When every
|
|
116
|
+
* arm refuses it throws the trailing {@link OrOptions} `fail` if given, else an auto list of the
|
|
117
|
+
* arms derived from the summary field, else a default refusal. The trailing options object does not
|
|
118
|
+
* count as an arm.
|
|
85
119
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
120
|
+
* @typeParam Gates - The tuple of two or more gate arms, tried left to right.
|
|
121
|
+
* @param gates - The gate arms to try in order, with an optional trailing {@link OrOptions} object.
|
|
122
|
+
*
|
|
123
|
+
* @see {@link and}
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* \@Gated(or(OwnerOnly(), RequireRole('123456789012345678')))
|
|
128
|
+
* \@SlashRoute('admin')
|
|
129
|
+
* class AdminHandler extends SlashHandler<'admin'> {
|
|
130
|
+
* async execute() {
|
|
131
|
+
* // ...
|
|
89
132
|
* }
|
|
133
|
+
* }
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function or<Gates extends TwoOrMore<Gate<GateContextBase>>>(...gates: Gates): Gate<RequiredOf<Gates[number]>, JoinNames<Gates, ' | '>>;
|
|
137
|
+
/**
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* // custom refusal when every arm refuses
|
|
141
|
+
* or(OwnerOnly(), RequireRole('123456789012345678'), { fail: new NotAllowedNotice() });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function or<Gates extends TwoOrMore<Gate<GateContextBase>>>(...args: [...Gates, OrOptions]): Gate<RequiredOf<Gates[number]>, JoinNames<Gates, ' | '>>;
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/gates/catalog/access.d.ts
|
|
147
|
+
/**
|
|
148
|
+
* Passes only for a user id listed in `config.ownerIds`, else refuses.
|
|
149
|
+
*
|
|
150
|
+
* Agnostic, so it attaches to interaction and event handlers alike. With no `ownerIds` configured it refuses every caller. Pass {@link GateNoticeOptions} to reword or replace the refusal.
|
|
151
|
+
*
|
|
152
|
+
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
153
|
+
*
|
|
154
|
+
* @see the `@Gated` decorator from `seedcord`
|
|
90
155
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* \@Gated(OwnerOnly())
|
|
159
|
+
* \@SlashRoute('shutdown')
|
|
160
|
+
* class ShutdownHandler extends SlashHandler<'shutdown'> {
|
|
161
|
+
* async execute() {
|
|
162
|
+
* // ...
|
|
93
163
|
* }
|
|
94
164
|
* }
|
|
165
|
+
* ```
|
|
95
166
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* // reword the refusal, keeping the embed styling
|
|
170
|
+
* OwnerOnly({ message: 'Owners only.' });
|
|
98
171
|
* ```
|
|
99
172
|
*/
|
|
100
|
-
declare
|
|
173
|
+
declare function OwnerOnly(options?: GateNoticeOptions): Gate<GateContextBase, 'OwnerOnly'>;
|
|
174
|
+
/**
|
|
175
|
+
* Passes inside a guild, else refuses.
|
|
176
|
+
*
|
|
177
|
+
* Agnostic, so it attaches to any handler kind. Often paired with `RequirePermissions` in an {@link and}.
|
|
178
|
+
*
|
|
179
|
+
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
180
|
+
*
|
|
181
|
+
* @see the `@Gated` decorator from `seedcord`
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
186
|
+
*
|
|
187
|
+
* \@Gated(GuildOnly(), RequirePermissions([PermissionFlagsBits.Administrator]))
|
|
188
|
+
* \@SlashRoute('maintenance')
|
|
189
|
+
* class Maintenance extends SlashHandler<'maintenance'> {
|
|
190
|
+
* async execute() {
|
|
191
|
+
* // ...
|
|
192
|
+
* }
|
|
193
|
+
* }
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare function GuildOnly(options?: GateNoticeOptions): Gate<GateContextBase, 'GuildOnly'>;
|
|
197
|
+
/**
|
|
198
|
+
* Passes in a direct message, else refuses.
|
|
199
|
+
*
|
|
200
|
+
* Agnostic, so it attaches to any handler kind. The inverse of {@link GuildOnly}, so combining the two in an {@link and} can never pass.
|
|
201
|
+
*
|
|
202
|
+
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
203
|
+
*
|
|
204
|
+
* @see the `@Gated` decorator from `seedcord`
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* \@Gated(DmOnly())
|
|
209
|
+
* \@SlashRoute('verify')
|
|
210
|
+
* class VerifyHandler extends SlashHandler<'verify'> {
|
|
211
|
+
* async execute() {
|
|
212
|
+
* // ...
|
|
213
|
+
* }
|
|
214
|
+
* }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
declare function DmOnly(options?: GateNoticeOptions): Gate<GateContextBase, 'DmOnly'>;
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/gates/catalog/Cooldown.d.ts
|
|
220
|
+
/**
|
|
221
|
+
* Options for {@link Cooldown}. `per` sets the bucket the window applies to and `limit` the uses allowed per
|
|
222
|
+
* window. `message` rewords the refusal and `notice` replaces it, both receiving the epoch ms the key frees
|
|
223
|
+
* up so the refusal can show the retry time.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* // one use per channel, rewording the refusal with the retry time
|
|
228
|
+
* Cooldown('10s', {
|
|
229
|
+
* per: 'channel',
|
|
230
|
+
* message: (resetAt) => `Slow down. Try again <t:${Math.round(resetAt / 1000)}:R>.`
|
|
231
|
+
* });
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```ts
|
|
236
|
+
* // five uses per minute, per user
|
|
237
|
+
* Cooldown('1m', { limit: 5 });
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
interface CooldownOptions {
|
|
101
241
|
/**
|
|
102
|
-
*
|
|
103
|
-
* bus. The user always sees {@link Notice.render} either way.
|
|
242
|
+
* The bucket the cooldown window applies to. 'user' scopes by user ID, falls back to global when the source carries no user id. 'guild' scopes by guild ID (falls back to global if no guild), and 'channel' scopes by channel ID (falls back to global if no channel).
|
|
104
243
|
*
|
|
105
|
-
* @defaultValue `
|
|
244
|
+
* @defaultValue `'user'`
|
|
106
245
|
*/
|
|
107
|
-
|
|
246
|
+
per?: 'user' | 'guild' | 'channel';
|
|
108
247
|
/**
|
|
109
|
-
*
|
|
110
|
-
* whole channel should see.
|
|
248
|
+
* Uses allowed inside one window before the gate refuses.
|
|
111
249
|
*
|
|
112
|
-
* @defaultValue `
|
|
250
|
+
* @defaultValue `1`
|
|
113
251
|
*/
|
|
114
|
-
|
|
252
|
+
limit?: number;
|
|
115
253
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
254
|
+
* Reword the refusal, keeping the standard notice card. Receives the epoch ms the key frees up, so the
|
|
255
|
+
* text can include the retry time with `<t:${Math.round(resetAt / 1000)}:R>`.
|
|
118
256
|
*/
|
|
119
|
-
|
|
120
|
-
protected constructor(message: string, options?: ErrorOptions);
|
|
257
|
+
message?: (resetAt: EpochMs) => string;
|
|
121
258
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
259
|
+
* Replace the refusal Notice entirely, for full control or a translated copy. Receives the epoch ms the
|
|
260
|
+
* key frees up.
|
|
124
261
|
*/
|
|
125
|
-
|
|
262
|
+
notice?: (resetAt: EpochMs) => Notice;
|
|
126
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Allows `limit` uses per window, scoped by `per`. A number `duration` is **seconds**, a string is
|
|
266
|
+
* a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError** at construction. The
|
|
267
|
+
* slot is charged in commit, only after the whole gate set passes, so a later refusal never burns the cooldown.
|
|
268
|
+
* That split also means two requests racing the same key can both pass before either charges the slot.
|
|
269
|
+
* The key combines the handler's route with the window settings, so two different handlers keep separate
|
|
270
|
+
* windows. Reword the refusal with {@link CooldownOptions.message} or replace it with {@link CooldownOptions.notice}.
|
|
271
|
+
*
|
|
272
|
+
* @param duration - A number is seconds, a string is a duration like `30m` or `24h`. An unparseable string throws a **SeedcordTypeError**.
|
|
273
|
+
* @param options - Sets the scope with `per`, the uses per window with `limit`, and the refusal text with `message` or `notice`.
|
|
274
|
+
*
|
|
275
|
+
* @see the `@Gated` decorator from `seedcord`
|
|
276
|
+
* @see {@link IRateLimiter}
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```ts
|
|
280
|
+
* // a number argument is SECONDS
|
|
281
|
+
* \@Gated(Cooldown(5))
|
|
282
|
+
* \@SlashRoute('daily')
|
|
283
|
+
* class DailyHandler extends SlashHandler<'daily'> {
|
|
284
|
+
* async execute() {
|
|
285
|
+
* // ...
|
|
286
|
+
* }
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* // a string is a duration, here scoped per guild (the default is per user)
|
|
293
|
+
* Cooldown('30m', { per: 'guild' });
|
|
294
|
+
* ```
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```ts
|
|
298
|
+
* // a burst, 3 uses per 10 minutes per user, then it refuses until a slot frees
|
|
299
|
+
* \@Gated(Cooldown('10m', { limit: 3 }))
|
|
300
|
+
* \@SlashRoute('report')
|
|
301
|
+
* class ReportHandler extends SlashHandler<'report'> {
|
|
302
|
+
* async execute() {
|
|
303
|
+
* // ...
|
|
304
|
+
* }
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
declare function Cooldown(duration: number | ValidDuration, options?: CooldownOptions): EffectGate<GateContextBase, 'Cooldown'>;
|
|
127
309
|
//#endregion
|
|
128
310
|
//#region src/stops/Fault.d.ts
|
|
129
311
|
/**
|
|
@@ -140,7 +322,7 @@ declare abstract class Notice extends Error {
|
|
|
140
322
|
*
|
|
141
323
|
* @example
|
|
142
324
|
* ```ts
|
|
143
|
-
* import { Fault } from 'seedcord';
|
|
325
|
+
* import { Fault } from '@seedcord/gateway';
|
|
144
326
|
*
|
|
145
327
|
* try {
|
|
146
328
|
* await db.write(record);
|
|
@@ -171,7 +353,7 @@ declare class Fault extends Notice {
|
|
|
171
353
|
*
|
|
172
354
|
* @example
|
|
173
355
|
* ```ts
|
|
174
|
-
* import { Silence } from 'seedcord';
|
|
356
|
+
* import { Silence } from '@seedcord/gateway';
|
|
175
357
|
*
|
|
176
358
|
* // before any reply or defer, drop the interaction with no reply and no report
|
|
177
359
|
* if (await isBlacklisted(interaction.user.id)) throw new Silence('blacklisted user');
|
|
@@ -218,5 +400,5 @@ declare function paginate<Item>(items: readonly Item[], page: number, perPage: n
|
|
|
218
400
|
/** Package version */
|
|
219
401
|
declare const version: string;
|
|
220
402
|
//#endregion
|
|
221
|
-
export { BuilderComponent, type BuilderType, CustomId, Fault, type MessageContextMenuRegistry, Notice, type OptionKind, type PageView, RowComponent, type RowType, Silence, type SlashOption, type SlashOptionRegistry, type UserContextMenuRegistry, paginate, version };
|
|
403
|
+
export { BuilderComponent, type BuilderType, Cooldown, type CooldownOptions, type CoreBase, CustomId, DispatchContext, type DispatchState, DmOnly, type EffectGate, Fault, type Gate, type GateContextBase, type GateNoticeOptions, GuildOnly, type MessageContextMenuRegistry, Notice, type OptionKind, OwnerOnly, type PageView, RegisterCommand, type RequiredOf, RowComponent, type RowType, Silence, type SlashOption, type SlashOptionRegistry, type UserContextMenuRegistry, and, defineEffectGate, defineGate, or, paginate, version };
|
|
222
404
|
//# sourceMappingURL=index.d.mts.map
|