@sapphire/decorators 7.0.0-pr-589.aa473f9.0 → 7.0.0-pr-935.7da5c8bb
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/CHANGELOG.md +55 -0
- package/README.md +0 -1
- package/dist/{index.js → cjs/index.cjs} +91 -20
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +503 -0
- package/dist/esm/index.d.mts +503 -0
- package/dist/{index.mjs → esm/index.mjs} +89 -21
- package/dist/esm/index.mjs.map +1 -0
- package/package.json +31 -24
- package/dist/index.d.ts +0 -240
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
import { PermissionResolvable, SlashCommandBuilder, SlashCommandSubcommandsOnlyBuilder, SlashCommandOptionsOnlyBuilder, ContextMenuCommandBuilder } from 'discord.js';
|
|
2
|
+
import { Piece, Command, ApplicationCommandRegistryRegisterOptions } from '@sapphire/framework';
|
|
3
|
+
import { Container } from '@sapphire/pieces';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decorator that sets the enumerable property of a class field to the desired value.
|
|
7
|
+
* @param value Whether the property should be enumerable or not
|
|
8
|
+
*/
|
|
9
|
+
declare function Enumerable(value: boolean): (target: object, key: string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Decorator that sets the enumerable property of a class method to the desired value.
|
|
12
|
+
* @param value Whether the method should be enumerable or not
|
|
13
|
+
*/
|
|
14
|
+
declare function EnumerableMethod(value: boolean): MethodDecorator;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The function precondition interface.
|
|
18
|
+
*/
|
|
19
|
+
interface FunctionPrecondition {
|
|
20
|
+
/**
|
|
21
|
+
* The arguments passed to the function or class' method.
|
|
22
|
+
*/
|
|
23
|
+
(...args: any[]): boolean | Promise<boolean>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The fallback interface, this is called when the function precondition returns or resolves with a falsy value.
|
|
27
|
+
*/
|
|
28
|
+
interface FunctionFallback {
|
|
29
|
+
/**
|
|
30
|
+
* The arguments passed to the function or class' method.
|
|
31
|
+
*/
|
|
32
|
+
(...args: any[]): unknown;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Utility to make a method decorator with lighter syntax and inferred types.
|
|
36
|
+
*
|
|
37
|
+
* ```typescript
|
|
38
|
+
* // Enumerable function
|
|
39
|
+
* function enumerableMethod(value: boolean) {
|
|
40
|
+
* return createMethodDecorator((_target, _propertyKey, descriptor) => {
|
|
41
|
+
* descriptor.enumerable = value;
|
|
42
|
+
* });
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
* @param fn The method to decorate
|
|
46
|
+
*/
|
|
47
|
+
declare function createMethodDecorator(fn: MethodDecorator): MethodDecorator;
|
|
48
|
+
/**
|
|
49
|
+
* Utility to make a class decorator with lighter syntax and inferred types.
|
|
50
|
+
* @param fn The class to decorate
|
|
51
|
+
* @see {@link ApplyOptions}
|
|
52
|
+
*/
|
|
53
|
+
declare function createClassDecorator<TFunction extends (...args: any[]) => void>(fn: TFunction): ClassDecorator;
|
|
54
|
+
/**
|
|
55
|
+
* Utility to make function preconditions.
|
|
56
|
+
*
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // No fallback (returns undefined)
|
|
59
|
+
* function requireGuild(value: number) {
|
|
60
|
+
* return createFunctionPrecondition((message: Message) =>
|
|
61
|
+
* message.guild !== null
|
|
62
|
+
* );
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // With fallback
|
|
66
|
+
* function requireGuild(
|
|
67
|
+
* value: number,
|
|
68
|
+
* fallback: () => unknown = () => undefined
|
|
69
|
+
* ) {
|
|
70
|
+
* return createFunctionPrecondition(
|
|
71
|
+
* (message: Message) => message.guild !== null,
|
|
72
|
+
* fallback
|
|
73
|
+
* );
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
* @since 1.0.0
|
|
77
|
+
* @param precondition The function that defines whether or not the function should be run, returning the returned value from fallback
|
|
78
|
+
* @param fallback The fallback value that defines what the method should return in case the precondition fails
|
|
79
|
+
*/
|
|
80
|
+
declare function createFunctionPrecondition(precondition: FunctionPrecondition, fallback?: FunctionFallback): MethodDecorator;
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new proxy to efficiently add properties to class without creating subclasses
|
|
83
|
+
* @param target The constructor of the class to modify
|
|
84
|
+
* @param handler The handler function to modify the constructor behavior for the target
|
|
85
|
+
* @hidden
|
|
86
|
+
*/
|
|
87
|
+
declare function createProxy<T extends object>(target: T, handler: Omit<ProxyHandler<T>, 'get'>): T;
|
|
88
|
+
|
|
89
|
+
declare enum DecoratorIdentifiers {
|
|
90
|
+
RequiresClientPermissionsGuildOnly = "requiresClientPermissionsGuildOnly",
|
|
91
|
+
RequiresClientPermissionsMissingPermissions = "requiresClientPermissionsMissingPermissions",
|
|
92
|
+
RequiresUserPermissionsGuildOnly = "requiresUserPermissionsGuildOnly",
|
|
93
|
+
RequiresUserPermissionsMissingPermissions = "requiresUserPermissionsMissingPermissions"
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Allows you to set permissions required for individual methods. This is particularly useful for subcommands that require specific permissions.
|
|
97
|
+
* @remark This decorator applies to the client that is to execute the command. For setting permissions required user of the command see {@link RequiresUserPermissions}
|
|
98
|
+
* @remark This decorator makes the decorated function asynchronous, so any result should be `await`ed.
|
|
99
|
+
* @param permissionsResolvable Permissions that the method should have.
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* import { ApplyOptions, RequiresClientPermissions } from '@sapphire/decorators';
|
|
103
|
+
* import { Subcommand } from '@sapphire/plugin-subcommands';
|
|
104
|
+
* import type { Message } from 'discord.js';
|
|
105
|
+
*
|
|
106
|
+
* (at)ApplyOptions<Subcommand.Options>({
|
|
107
|
+
* aliases: ['cws'],
|
|
108
|
+
* description: 'A basic command with some subcommands',
|
|
109
|
+
* subCommands: ['add', 'remove', 'reset', { input: 'show', default: true }]
|
|
110
|
+
* })
|
|
111
|
+
* export default class extends Subcommand {
|
|
112
|
+
* // Anyone should be able to view the result, but not modify
|
|
113
|
+
* public async show(message: Message) {
|
|
114
|
+
* return message.channel.send('Showing!');
|
|
115
|
+
* }
|
|
116
|
+
*
|
|
117
|
+
* (at)RequiresClientPermissions('BAN_MEMBERS') // This subcommand requires the client to be able to ban members.
|
|
118
|
+
* public async add(message: Message) {
|
|
119
|
+
* return message.channel.send('Adding!');
|
|
120
|
+
* }
|
|
121
|
+
*
|
|
122
|
+
* (at)RequiresClientPermissions('BAN_MEMBERS') // This subcommand requires the client to be able to ban members.
|
|
123
|
+
* public async remove(message: Message) {
|
|
124
|
+
* return message.channel.send('Removing!');
|
|
125
|
+
* }
|
|
126
|
+
*
|
|
127
|
+
* (at)RequiresClientPermissions('BAN_MEMBERS') // This subcommand requires the client to be able to ban members.
|
|
128
|
+
* public async reset(message: Message) {
|
|
129
|
+
* return message.channel.send('Resetting!');
|
|
130
|
+
* }
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
declare const RequiresClientPermissions: (...permissionsResolvable: PermissionResolvable[]) => MethodDecorator;
|
|
135
|
+
/**
|
|
136
|
+
* Allows you to set permissions required for individual methods. This is particularly useful for subcommands that require specific permissions.
|
|
137
|
+
* @remark This decorator applies to the user of the command. For setting permissions required for the client see {@link RequiresClientPermissions}
|
|
138
|
+
* @remark This decorator makes the decorated function asynchronous, so any result should be `await`ed.
|
|
139
|
+
* @param permissionsResolvable Permissions that the method should have.
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* import { ApplyOptions, RequiresUserPermissions } from '@sapphire/decorators';
|
|
143
|
+
* import { Subcommand } from '@sapphire/plugin-subcommands';
|
|
144
|
+
* import type { Message } from 'discord.js';
|
|
145
|
+
*
|
|
146
|
+
* (at)ApplyOptions<Subcommand.Options>({
|
|
147
|
+
* aliases: ['cws'],
|
|
148
|
+
* description: 'A basic command with some subcommands',
|
|
149
|
+
* subCommands: ['add', 'remove', 'reset', { input: 'show', default: true }]
|
|
150
|
+
* })
|
|
151
|
+
* export default class extends Subcommand {
|
|
152
|
+
* // Anyone should be able to view the result, but not modify
|
|
153
|
+
* public async show(message: Message) {
|
|
154
|
+
* return message.channel.send('Showing!');
|
|
155
|
+
* }
|
|
156
|
+
*
|
|
157
|
+
* (at)RequiresUserPermissions('BAN_MEMBERS') // This subcommand requires the user of the command to be able to ban members.
|
|
158
|
+
* public async add(message: Message) {
|
|
159
|
+
* return message.channel.send('Adding!');
|
|
160
|
+
* }
|
|
161
|
+
*
|
|
162
|
+
* (at)RequiresUserPermissions('BAN_MEMBERS') // This subcommand requires the user of the command to be able to ban members.
|
|
163
|
+
* public async remove(message: Message) {
|
|
164
|
+
* return message.channel.send('Removing!');
|
|
165
|
+
* }
|
|
166
|
+
*
|
|
167
|
+
* (at)RequiresUserPermissions('BAN_MEMBERS') // This subcommand requires the user of the command to be able to ban members.
|
|
168
|
+
* public async reset(message: Message) {
|
|
169
|
+
* return message.channel.send('Resetting!');
|
|
170
|
+
* }
|
|
171
|
+
* }
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
declare const RequiresUserPermissions: (...permissionsResolvable: PermissionResolvable[]) => MethodDecorator;
|
|
175
|
+
/**
|
|
176
|
+
* Requires the message to be run in a guild context, this decorator requires the first argument to be a {@link Message} or {@link BaseInteraction} instance which includes all interaction types
|
|
177
|
+
* @since 1.0.0
|
|
178
|
+
* @param fallback The fallback value passed to {@link createFunctionPrecondition}
|
|
179
|
+
*/
|
|
180
|
+
declare function RequiresGuildContext(fallback?: FunctionFallback): MethodDecorator;
|
|
181
|
+
/**
|
|
182
|
+
* Requires the message to be run in a dm context, this decorator requires the first argument to be a {@link Message} or {@link BaseInteraction} instance which includes all interaction types
|
|
183
|
+
* @since 1.0.0
|
|
184
|
+
* @param fallback The fallback value passed to {@link createFunctionPrecondition}
|
|
185
|
+
*/
|
|
186
|
+
declare function RequiresDMContext(fallback?: FunctionFallback): MethodDecorator;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Decorator function that applies given options to any Sapphire piece
|
|
190
|
+
* @param optionsOrFn The options or function that returns options to pass to the piece constructor
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* import { ApplyOptions } from '@sapphire/decorators';
|
|
194
|
+
* import { Command } from '@sapphire/framework';
|
|
195
|
+
* import type { Message } from 'discord.js';
|
|
196
|
+
*
|
|
197
|
+
* @ApplyOptions<Command.Options>({
|
|
198
|
+
* description: 'ping pong',
|
|
199
|
+
* enabled: true
|
|
200
|
+
* })
|
|
201
|
+
* export class UserCommand extends Command {
|
|
202
|
+
* public override async messageRun(message: Message) {
|
|
203
|
+
* const msg = await message.channel.send('Ping?');
|
|
204
|
+
*
|
|
205
|
+
* return msg.edit(
|
|
206
|
+
* `Pong! Client Latency ${Math.round(this.container.client.ws.ping)}ms. API Latency ${msg.createdTimestamp - message.createdTimestamp}ms.`
|
|
207
|
+
* );
|
|
208
|
+
* }
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* import { ApplyOptions } from '@sapphire/decorators';
|
|
214
|
+
* import { Listener } from '@sapphire/framework';
|
|
215
|
+
* import { GatewayDispatchEvents, GatewayMessageDeleteDispatch } from 'discord.js';
|
|
216
|
+
*
|
|
217
|
+
* @ApplyOptions<Listener.Options>(({ container }) => ({
|
|
218
|
+
* description: 'Handle Raw Message Delete events',
|
|
219
|
+
* emitter: container.client.ws,
|
|
220
|
+
* event: GatewayDispatchEvents.MessageDelete
|
|
221
|
+
* }))
|
|
222
|
+
* export class UserListener extends Listener {
|
|
223
|
+
* public override run(data: GatewayMessageDeleteDispatch['d']): void {
|
|
224
|
+
* if (!data.guild_id) return;
|
|
225
|
+
*
|
|
226
|
+
* const guild = this.container.client.guilds.cache.get(data.guild_id);
|
|
227
|
+
* if (!guild || !guild.channels.cache.has(data.channel_id)) return;
|
|
228
|
+
*
|
|
229
|
+
* // Do something with the data
|
|
230
|
+
* }
|
|
231
|
+
* }
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
declare function ApplyOptions<T extends Piece.Options>(optionsOrFn: T | ((parameters: ApplyOptionsCallbackParameters) => T)): ClassDecorator;
|
|
235
|
+
/**
|
|
236
|
+
* Decorator for registering chat input command.
|
|
237
|
+
* @param optionsFn The function that returns options to pass to the registry.
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* import { RegisterChatInputCommand } from '@sapphire/decorators';
|
|
241
|
+
* import { Command } from '@sapphire/framework';
|
|
242
|
+
*
|
|
243
|
+
* (at)RegisterChatInputCommand((builder, command) => builder
|
|
244
|
+
* .setName(command.name)
|
|
245
|
+
* .setDescription(command.description)
|
|
246
|
+
* )
|
|
247
|
+
* export class UserCommand extends Command {
|
|
248
|
+
* public override chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
|
249
|
+
* return interaction.reply({ content: 'HI!' });
|
|
250
|
+
* }
|
|
251
|
+
* }
|
|
252
|
+
* ```
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* import { RegisterChatInputCommand } from '@sapphire/decorators';
|
|
256
|
+
* import { Command } from '@sapphire/framework';
|
|
257
|
+
*
|
|
258
|
+
* (at)RegisterChatInputCommand((builder, command) => builder
|
|
259
|
+
* .setName(command.name)
|
|
260
|
+
* .setDescription(command.description),
|
|
261
|
+
* {
|
|
262
|
+
* idHints: ['737141877803057244'],
|
|
263
|
+
* guildIds: ['737141877803057244']
|
|
264
|
+
* }
|
|
265
|
+
* )
|
|
266
|
+
* export class UserCommand extends Command {
|
|
267
|
+
* public override chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
|
268
|
+
* return interaction.reply({ content: 'HI!' });
|
|
269
|
+
* }
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* import { RegisterChatInputCommand } from '@sapphire/decorators';
|
|
275
|
+
* import { Command } from '@sapphire/framework';
|
|
276
|
+
*
|
|
277
|
+
* (at)RegisterChatInputCommand((builder) => builder
|
|
278
|
+
* .setName('hi')
|
|
279
|
+
* .setDescription('Sends a hi message')
|
|
280
|
+
* )
|
|
281
|
+
* export class UserCommand extends Command {
|
|
282
|
+
* public override chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
|
283
|
+
* return interaction.reply({ content: 'HI!' });
|
|
284
|
+
* }
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* import { ApplyOptions, RegisterChatInputCommand } from '@sapphire/decorators';
|
|
290
|
+
* import { Command } from '@sapphire/framework';
|
|
291
|
+
* import type { Message } from 'discord.js';
|
|
292
|
+
*
|
|
293
|
+
* (at)ApplyOptions<Command.Options>({
|
|
294
|
+
* description: 'ping pong',
|
|
295
|
+
* enabled: true
|
|
296
|
+
* })
|
|
297
|
+
* (at)RegisterChatInputCommand((builder, command) => builder
|
|
298
|
+
* .setName(command.name)
|
|
299
|
+
* .setDescription(command.description)
|
|
300
|
+
* )
|
|
301
|
+
* export class UserCommand extends Command { *
|
|
302
|
+
* public override chatInputRun(interaction: Command.ChatInputCommandInteraction) {
|
|
303
|
+
* return interaction.reply({ content: 'HI!' });
|
|
304
|
+
* }
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
declare function RegisterChatInputCommand<CMD extends Command = Command>(optionsFn: ChatInputCommandDecoratorsMap<CMD>['optionsFn'], registryOptions?: ApplicationCommandRegistryRegisterOptions): ClassDecorator;
|
|
309
|
+
/**
|
|
310
|
+
* Decorator for registering message context menu command.
|
|
311
|
+
* @param optionsFn The function that returns options to pass to the registry.
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* import { RegisterMessageContextMenuCommand } from '@sapphire/decorators';
|
|
315
|
+
* import { Command } from '@sapphire/framework';
|
|
316
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
317
|
+
*
|
|
318
|
+
* (at)RegisterMessageContextMenuCommand((builder, command) => builder
|
|
319
|
+
* .setName(command.name)
|
|
320
|
+
* .setContexts(InteractionContextType.Guild)
|
|
321
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
322
|
+
* )
|
|
323
|
+
* export class UserCommand extends Command {
|
|
324
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
325
|
+
* return interaction.reply({ content: 'HI!' })
|
|
326
|
+
* }
|
|
327
|
+
* }
|
|
328
|
+
* ```
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* import { RegisterMessageContextMenuCommand } from '@sapphire/decorators';
|
|
332
|
+
* import { Command } from '@sapphire/framework';
|
|
333
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
334
|
+
*
|
|
335
|
+
* (at)RegisterMessageContextMenuCommand((builder, command) => builder
|
|
336
|
+
* .setName(command.name)
|
|
337
|
+
* .setContexts(InteractionContextType.Guild)
|
|
338
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall),
|
|
339
|
+
* {
|
|
340
|
+
* idHints: ['737141877803057244'],
|
|
341
|
+
* guildIds: ['737141877803057244']
|
|
342
|
+
* }
|
|
343
|
+
* )
|
|
344
|
+
* export class UserCommand extends Command {
|
|
345
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
346
|
+
* return interaction.reply({ content: 'HI!' })
|
|
347
|
+
* }
|
|
348
|
+
* }
|
|
349
|
+
* ```
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* import { RegisterMessageContextMenuCommand } from '@sapphire/decorators';
|
|
353
|
+
* import { Command } from '@sapphire/framework';
|
|
354
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
355
|
+
*
|
|
356
|
+
* (at)RegisterMessageContextMenuCommand((builder, command) => builder
|
|
357
|
+
* .setName(command.name)
|
|
358
|
+
* .setContexts(InteractionContextType.Guild)
|
|
359
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
360
|
+
* )
|
|
361
|
+
* export class UserCommand extends Command {
|
|
362
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
363
|
+
* return interaction.reply({ content: 'HI!' })
|
|
364
|
+
* }
|
|
365
|
+
* }
|
|
366
|
+
* ```
|
|
367
|
+
* @example
|
|
368
|
+
* ```typescript
|
|
369
|
+
* import { RegisterMessageContextMenuCommand } from '@sapphire/decorators';
|
|
370
|
+
* import { Command } from '@sapphire/framework';
|
|
371
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
372
|
+
*
|
|
373
|
+
* (at)RegisterMessageContextMenuCommand((builder) => builder
|
|
374
|
+
* .setName('Send HI')
|
|
375
|
+
* .setContexts(InteractionContextType.Guild)
|
|
376
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
377
|
+
* )
|
|
378
|
+
* export class UserCommand extends Command {
|
|
379
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
380
|
+
* return interaction.reply({ content: 'HI!' })
|
|
381
|
+
* }
|
|
382
|
+
* }
|
|
383
|
+
* ```
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* import { ApplyOptions, RegisterMessageContextMenuCommand } from '@sapphire/decorators';
|
|
387
|
+
* import { Command } from '@sapphire/framework';
|
|
388
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
389
|
+
*
|
|
390
|
+
* (at)ApplyOptions<Command.Options>({
|
|
391
|
+
* enabled: true
|
|
392
|
+
* })
|
|
393
|
+
* (at)RegisterMessageContextMenuCommand((builder, command) => builder
|
|
394
|
+
* .setName(command.name)
|
|
395
|
+
* .setContexts(InteractionContextType.Guild)
|
|
396
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
397
|
+
* )
|
|
398
|
+
* export class UserCommand extends Command {
|
|
399
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
400
|
+
* return interaction.reply({ content: 'HI!' })
|
|
401
|
+
* }
|
|
402
|
+
* }
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
declare function RegisterMessageContextMenuCommand<CMD extends Command = Command>(optionsFn: ContextMenuCommandDecoratorsMap<CMD>['optionsFn'], registryOptions?: ApplicationCommandRegistryRegisterOptions): ClassDecorator;
|
|
406
|
+
/**
|
|
407
|
+
* Decorator for registering user context menu command.
|
|
408
|
+
* @param optionsFn The function that returns options to pass to the registry.
|
|
409
|
+
* @example
|
|
410
|
+
* ```typescript
|
|
411
|
+
* import { RegisterUserContextMenuCommand } from '@sapphire/decorators';
|
|
412
|
+
* import { Command } from '@sapphire/framework';
|
|
413
|
+
* import { ApplicationIntegrationType, InteractionContextType, type UserContextMenuCommandInteraction } from 'discord.js';
|
|
414
|
+
*
|
|
415
|
+
* (at)RegisterUserContextMenuCommand((builder, command) => builder
|
|
416
|
+
* .setName(command.name)
|
|
417
|
+
* .setContexts(InteractionContextType.Guild)
|
|
418
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
419
|
+
* )
|
|
420
|
+
* export class UserCommand extends Command {
|
|
421
|
+
* public override contextMenuRun(interaction: UserContextMenuCommandInteraction) {
|
|
422
|
+
* return interaction.reply({ content: 'HI!' })
|
|
423
|
+
* }
|
|
424
|
+
* }
|
|
425
|
+
* ```
|
|
426
|
+
* ```
|
|
427
|
+
* @example
|
|
428
|
+
* ```typescript
|
|
429
|
+
* import { RegisterUserContextMenuCommand } from '@sapphire/decorators';
|
|
430
|
+
* import { Command } from '@sapphire/framework';
|
|
431
|
+
* import { ApplicationIntegrationType, InteractionContextType, type MessageContextMenuCommandInteraction } from 'discord.js';
|
|
432
|
+
*
|
|
433
|
+
* (at)RegisterUserContextMenuCommand((builder, command) => builder
|
|
434
|
+
* .setName(command.name)
|
|
435
|
+
* .setContexts(InteractionContextType.Guild)
|
|
436
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall),
|
|
437
|
+
* {
|
|
438
|
+
* idHints: ['737141877803057244'],
|
|
439
|
+
* guildIds: ['737141877803057244']
|
|
440
|
+
* }
|
|
441
|
+
* )
|
|
442
|
+
* export class UserCommand extends Command {
|
|
443
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
444
|
+
* return interaction.reply({ content: 'HI!' })
|
|
445
|
+
* }
|
|
446
|
+
* }
|
|
447
|
+
* ```
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* import { RegisterUserContextMenuCommand } from '@sapphire/decorators';
|
|
451
|
+
* import { Command } from '@sapphire/framework';
|
|
452
|
+
* import { ApplicationIntegrationType, InteractionContextType, type UserContextMenuCommandInteraction } from 'discord.js';
|
|
453
|
+
*
|
|
454
|
+
* (at)RegisterUserContextMenuCommand((builder, command) => builder
|
|
455
|
+
* .setName('Send HI')
|
|
456
|
+
* .setContexts(InteractionContextType.Guild)
|
|
457
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
458
|
+
* )
|
|
459
|
+
* export class UserCommand extends Command {
|
|
460
|
+
* public override contextMenuRun(interaction: UserContextMenuCommandInteraction) {
|
|
461
|
+
* return interaction.reply({ content: `HI ${interaction.targetUser}!` })
|
|
462
|
+
* }
|
|
463
|
+
* }
|
|
464
|
+
* ```
|
|
465
|
+
* @example
|
|
466
|
+
* ```typescript
|
|
467
|
+
* import { ApplyOptions, RegisterUserContextMenuCommand } from '@sapphire/decorators';
|
|
468
|
+
* import { Command } from '@sapphire/framework';
|
|
469
|
+
* import { ApplicationIntegrationType, InteractionContextType, type UserContextMenuCommandInteraction } from 'discord.js';
|
|
470
|
+
*
|
|
471
|
+
* (at)ApplyOptions<Command.Options>({
|
|
472
|
+
* enabled: true
|
|
473
|
+
* })
|
|
474
|
+
* (at)RegisterUserContextMenuCommand((builder, command) => builder
|
|
475
|
+
* .setName(command.name)
|
|
476
|
+
* .setContexts(InteractionContextType.Guild)
|
|
477
|
+
* .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
|
478
|
+
* )
|
|
479
|
+
* export class UserCommand extends Command {
|
|
480
|
+
* public override contextMenuRun(interaction: MessageContextMenuCommandInteraction) {
|
|
481
|
+
* return interaction.reply({ content: 'HI!' })
|
|
482
|
+
* }
|
|
483
|
+
* }
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function RegisterUserContextMenuCommand<CMD extends Command = Command>(optionsFn: ContextMenuCommandDecoratorsMap<CMD>['optionsFn'], registryOptions?: ApplicationCommandRegistryRegisterOptions): ClassDecorator;
|
|
487
|
+
interface ApplyOptionsCallbackParameters {
|
|
488
|
+
container: Container;
|
|
489
|
+
context: Piece.LoaderContext;
|
|
490
|
+
}
|
|
491
|
+
interface ChatInputCommandDecoratorsMap<CMD extends Command> {
|
|
492
|
+
type: 'RegisterChatInputCommand';
|
|
493
|
+
optionsFn: (builder: SlashCommandBuilder, command: ThisType<CMD> & CMD) => SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder | SlashCommandOptionsOnlyBuilder;
|
|
494
|
+
registryOptions?: ApplicationCommandRegistryRegisterOptions;
|
|
495
|
+
}
|
|
496
|
+
interface ContextMenuCommandDecoratorsMap<CMD extends Command> {
|
|
497
|
+
type: 'RegisterMessageContextMenuCommand' | 'RegisterUserContextMenuCommand';
|
|
498
|
+
optionsFn: (builder: ContextMenuCommandBuilder, //
|
|
499
|
+
command: ThisType<CMD> & CMD) => ContextMenuCommandBuilder;
|
|
500
|
+
registryOptions?: ApplicationCommandRegistryRegisterOptions;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export { ApplyOptions, type ApplyOptionsCallbackParameters, DecoratorIdentifiers, Enumerable, EnumerableMethod, type FunctionFallback, type FunctionPrecondition, RegisterChatInputCommand, RegisterMessageContextMenuCommand, RegisterUserContextMenuCommand, RequiresClientPermissions, RequiresDMContext, RequiresGuildContext, RequiresUserPermissions, createClassDecorator, createFunctionPrecondition, createMethodDecorator, createProxy };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isDMChannel, isGuildBasedChannel } from '@sapphire/discord.js-utilities';
|
|
2
2
|
import { UserError, container } from '@sapphire/framework';
|
|
3
|
-
import {
|
|
3
|
+
import { isNullish } from '@sapphire/utilities';
|
|
4
|
+
import { PermissionsBitField, PermissionFlagsBits, ApplicationCommandType } from 'discord.js';
|
|
4
5
|
|
|
5
6
|
var __defProp = Object.defineProperty;
|
|
6
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -17,10 +18,8 @@ __name(createClassDecorator, "createClassDecorator");
|
|
|
17
18
|
function createFunctionPrecondition(precondition, fallback = () => void 0) {
|
|
18
19
|
return createMethodDecorator((_target, _propertyKey, descriptor) => {
|
|
19
20
|
const method = descriptor.value;
|
|
20
|
-
if (!method)
|
|
21
|
-
|
|
22
|
-
if (typeof method !== "function")
|
|
23
|
-
throw new Error("Function preconditions can only be applied to functions.");
|
|
21
|
+
if (!method) throw new Error("Function preconditions require a [[value]].");
|
|
22
|
+
if (typeof method !== "function") throw new Error("Function preconditions can only be applied to functions.");
|
|
24
23
|
descriptor.value = /* @__PURE__ */ __name(async function descriptorValue(...args) {
|
|
25
24
|
const canRun = await precondition(...args);
|
|
26
25
|
return canRun ? method.call(this, ...args) : fallback.call(this, ...args);
|
|
@@ -31,10 +30,10 @@ __name(createFunctionPrecondition, "createFunctionPrecondition");
|
|
|
31
30
|
function createProxy(target, handler) {
|
|
32
31
|
return new Proxy(target, {
|
|
33
32
|
...handler,
|
|
34
|
-
get: (target2, property) => {
|
|
33
|
+
get: /* @__PURE__ */ __name((target2, property) => {
|
|
35
34
|
const value = Reflect.get(target2, property);
|
|
36
35
|
return typeof value === "function" ? (...args) => value.apply(target2, args) : value;
|
|
37
|
-
}
|
|
36
|
+
}, "get")
|
|
38
37
|
});
|
|
39
38
|
}
|
|
40
39
|
__name(createProxy, "createProxy");
|
|
@@ -97,15 +96,17 @@ var DMAvailableUserPermissions = new PermissionsBitField(
|
|
|
97
96
|
var RequiresClientPermissions = /* @__PURE__ */ __name((...permissionsResolvable) => {
|
|
98
97
|
const resolved = new PermissionsBitField(permissionsResolvable);
|
|
99
98
|
const resolvedIncludesServerPermissions = Boolean(resolved.bitfield & DMAvailablePermissions.bitfield);
|
|
100
|
-
return createFunctionPrecondition((
|
|
101
|
-
|
|
99
|
+
return createFunctionPrecondition((context) => {
|
|
100
|
+
const { channel } = context;
|
|
101
|
+
const member = context.guild?.members.me;
|
|
102
|
+
if (resolvedIncludesServerPermissions && isDMChannel(channel)) {
|
|
102
103
|
throw new UserError({
|
|
103
104
|
identifier: "requiresClientPermissionsGuildOnly" /* RequiresClientPermissionsGuildOnly */,
|
|
104
105
|
message: "Sorry, but that command can only be used in a server because I do not have sufficient permissions in DMs"
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
|
-
if (isGuildBasedChannel(
|
|
108
|
-
const missingPermissions =
|
|
108
|
+
if (isGuildBasedChannel(channel) && !isNullish(member)) {
|
|
109
|
+
const missingPermissions = channel.permissionsFor(member).missing(resolved);
|
|
109
110
|
if (missingPermissions.length) {
|
|
110
111
|
throw new UserError({
|
|
111
112
|
identifier: "requiresClientPermissionsMissingPermissions" /* RequiresClientPermissionsMissingPermissions */,
|
|
@@ -122,15 +123,17 @@ var RequiresClientPermissions = /* @__PURE__ */ __name((...permissionsResolvable
|
|
|
122
123
|
var RequiresUserPermissions = /* @__PURE__ */ __name((...permissionsResolvable) => {
|
|
123
124
|
const resolved = new PermissionsBitField(permissionsResolvable);
|
|
124
125
|
const resolvedIncludesServerPermissions = Boolean(resolved.bitfield & DMAvailableUserPermissions.bitfield);
|
|
125
|
-
return createFunctionPrecondition((
|
|
126
|
-
|
|
126
|
+
return createFunctionPrecondition((context) => {
|
|
127
|
+
const { channel } = context;
|
|
128
|
+
const member = context.guild?.members.me;
|
|
129
|
+
if (resolvedIncludesServerPermissions && isDMChannel(channel)) {
|
|
127
130
|
throw new UserError({
|
|
128
131
|
identifier: "requiresUserPermissionsGuildOnly" /* RequiresUserPermissionsGuildOnly */,
|
|
129
132
|
message: "Sorry, but that command can only be used in a server because you do not have sufficient permissions in DMs"
|
|
130
133
|
});
|
|
131
134
|
}
|
|
132
|
-
if (isGuildBasedChannel(
|
|
133
|
-
const missingPermissions =
|
|
135
|
+
if (isGuildBasedChannel(channel) && !isNullish(member)) {
|
|
136
|
+
const missingPermissions = channel.permissionsFor(member).missing(resolved);
|
|
134
137
|
if (missingPermissions.length) {
|
|
135
138
|
throw new UserError({
|
|
136
139
|
identifier: "requiresUserPermissionsMissingPermissions" /* RequiresUserPermissionsMissingPermissions */,
|
|
@@ -145,25 +148,90 @@ var RequiresUserPermissions = /* @__PURE__ */ __name((...permissionsResolvable)
|
|
|
145
148
|
});
|
|
146
149
|
}, "RequiresUserPermissions");
|
|
147
150
|
function RequiresGuildContext(fallback = () => void 0) {
|
|
148
|
-
return createFunctionPrecondition((
|
|
151
|
+
return createFunctionPrecondition((context) => context.guild !== null, fallback);
|
|
149
152
|
}
|
|
150
153
|
__name(RequiresGuildContext, "RequiresGuildContext");
|
|
151
154
|
function RequiresDMContext(fallback = () => void 0) {
|
|
152
|
-
return createFunctionPrecondition((
|
|
155
|
+
return createFunctionPrecondition((context) => context.guild === null, fallback);
|
|
153
156
|
}
|
|
154
157
|
__name(RequiresDMContext, "RequiresDMContext");
|
|
158
|
+
var applicationDecoratorsMap = /* @__PURE__ */ new WeakMap();
|
|
159
|
+
var proxyApplicationCommandToOriginal = /* @__PURE__ */ new WeakMap();
|
|
160
|
+
var originalApplicationCommandToProxy = /* @__PURE__ */ new WeakMap();
|
|
155
161
|
function ApplyOptions(optionsOrFn) {
|
|
156
162
|
return createClassDecorator(
|
|
157
163
|
(target) => createProxy(target, {
|
|
158
|
-
construct: (ctor, [context, baseOptions = {}]) => new ctor(context, {
|
|
164
|
+
construct: /* @__PURE__ */ __name((ctor, [context, baseOptions = {}]) => new ctor(context, {
|
|
159
165
|
...baseOptions,
|
|
160
166
|
...typeof optionsOrFn === "function" ? optionsOrFn({ container, context }) : optionsOrFn
|
|
161
|
-
})
|
|
167
|
+
}), "construct")
|
|
162
168
|
})
|
|
163
169
|
);
|
|
164
170
|
}
|
|
165
171
|
__name(ApplyOptions, "ApplyOptions");
|
|
172
|
+
function RegisterChatInputCommand(optionsFn, registryOptions) {
|
|
173
|
+
return createClassDecorator(
|
|
174
|
+
(target) => collectApplicationCommandDecorators(target, { type: "RegisterChatInputCommand", optionsFn, registryOptions })
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
__name(RegisterChatInputCommand, "RegisterChatInputCommand");
|
|
178
|
+
function RegisterMessageContextMenuCommand(optionsFn, registryOptions) {
|
|
179
|
+
return createClassDecorator(
|
|
180
|
+
(target) => collectApplicationCommandDecorators(target, { type: "RegisterMessageContextMenuCommand", optionsFn, registryOptions })
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
__name(RegisterMessageContextMenuCommand, "RegisterMessageContextMenuCommand");
|
|
184
|
+
function RegisterUserContextMenuCommand(optionsFn, registryOptions) {
|
|
185
|
+
return createClassDecorator(
|
|
186
|
+
(target) => collectApplicationCommandDecorators(target, { type: "RegisterUserContextMenuCommand", optionsFn, registryOptions })
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
__name(RegisterUserContextMenuCommand, "RegisterUserContextMenuCommand");
|
|
190
|
+
function collectApplicationCommandDecorators(target, decorator) {
|
|
191
|
+
const original = proxyApplicationCommandToOriginal.get(target) ?? target;
|
|
192
|
+
const exisiting = applicationDecoratorsMap.get(original) ?? [];
|
|
193
|
+
exisiting.push(decorator);
|
|
194
|
+
applicationDecoratorsMap.set(original, exisiting);
|
|
195
|
+
if (originalApplicationCommandToProxy.has(original)) return originalApplicationCommandToProxy.get(original);
|
|
196
|
+
const proxied = createProxy(target, {
|
|
197
|
+
construct(originalTarget, argArray) {
|
|
198
|
+
const command = Reflect.construct(originalTarget, argArray);
|
|
199
|
+
const decorators = applicationDecoratorsMap.get(original);
|
|
200
|
+
const originalRegister = command.registerApplicationCommands?.bind(command);
|
|
201
|
+
command.registerApplicationCommands = /* @__PURE__ */ __name(function registerApplicationCommands(registry) {
|
|
202
|
+
for (const deco of decorators) {
|
|
203
|
+
switch (deco.type) {
|
|
204
|
+
case "RegisterChatInputCommand": {
|
|
205
|
+
registry.registerChatInputCommand((builder) => deco.optionsFn(builder, command), deco.registryOptions);
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case "RegisterMessageContextMenuCommand": {
|
|
209
|
+
registry.registerContextMenuCommand(
|
|
210
|
+
(builder) => deco.optionsFn(builder, command).setType(ApplicationCommandType.Message),
|
|
211
|
+
deco.registryOptions
|
|
212
|
+
);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case "RegisterUserContextMenuCommand": {
|
|
216
|
+
registry.registerContextMenuCommand(
|
|
217
|
+
(builder) => deco.optionsFn(builder, command).setType(ApplicationCommandType.User),
|
|
218
|
+
deco.registryOptions
|
|
219
|
+
);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (originalRegister) return originalRegister.call(this, registry);
|
|
225
|
+
}, "registerApplicationCommands");
|
|
226
|
+
return command;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
proxyApplicationCommandToOriginal.set(proxied, original);
|
|
230
|
+
originalApplicationCommandToProxy.set(original, proxied);
|
|
231
|
+
return proxied;
|
|
232
|
+
}
|
|
233
|
+
__name(collectApplicationCommandDecorators, "collectApplicationCommandDecorators");
|
|
166
234
|
|
|
167
|
-
export { ApplyOptions, DecoratorIdentifiers, Enumerable, EnumerableMethod, RequiresClientPermissions, RequiresDMContext, RequiresGuildContext, RequiresUserPermissions, createClassDecorator, createFunctionPrecondition, createMethodDecorator, createProxy };
|
|
168
|
-
//# sourceMappingURL=
|
|
235
|
+
export { ApplyOptions, DecoratorIdentifiers, Enumerable, EnumerableMethod, RegisterChatInputCommand, RegisterMessageContextMenuCommand, RegisterUserContextMenuCommand, RequiresClientPermissions, RequiresDMContext, RequiresGuildContext, RequiresUserPermissions, createClassDecorator, createFunctionPrecondition, createMethodDecorator, createProxy };
|
|
236
|
+
//# sourceMappingURL=index.mjs.map
|
|
169
237
|
//# sourceMappingURL=index.mjs.map
|