@lunibee/builders 0.2.3 → 0.3.0
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/package.json +2 -2
- package/src/attachment.ts +27 -11
- package/src/commands.ts +199 -324
- package/src/components.ts +30 -181
- package/src/embed.ts +66 -62
- package/src/index.ts +0 -47
package/src/commands.ts
CHANGED
|
@@ -29,14 +29,14 @@ function validateContexts(contexts: number[]): void {
|
|
|
29
29
|
/** Builds Discord application command payloads. */
|
|
30
30
|
export class CreateSlashCommand {
|
|
31
31
|
readonly #data: Record<string, unknown> = { type: 1 };
|
|
32
|
-
/** Sets the command name. */
|
|
32
|
+
/** Sets the command name. */
|
|
33
|
+
public setName(name: string): this {
|
|
33
34
|
validateName(name, "Command name");
|
|
34
35
|
this.#data.name = name;
|
|
35
36
|
return this;
|
|
36
37
|
}
|
|
37
|
-
/** Sets the command description. */
|
|
38
|
-
|
|
39
|
-
): this {
|
|
38
|
+
/** Sets the command description. */
|
|
39
|
+
public setDescription(description: string): this {
|
|
40
40
|
validateText(description, "Command description", 100);
|
|
41
41
|
this.#data.description = description;
|
|
42
42
|
return this;
|
|
@@ -47,11 +47,6 @@ export class CreateSlashCommand {
|
|
|
47
47
|
this.#data.contexts = [...contexts];
|
|
48
48
|
return this;
|
|
49
49
|
}
|
|
50
|
-
/** @deprecated Discord deprecated `dm_permission`. Use {@link CreateSlashCommand.setContexts}: `setContexts(0)` for guilds only, `setContexts(0, 1)` to allow the bot's DMs. Removed in 0.3.0. */
|
|
51
|
-
public setDMPermission(enabled: boolean): this {
|
|
52
|
-
this.#data.dm_permission = enabled;
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
50
|
/** Sets whether the command is NSFW. */
|
|
56
51
|
public setNSFW(nsfw = true): this {
|
|
57
52
|
this.#data.nsfw = nsfw;
|
|
@@ -61,110 +56,96 @@ export class CreateSlashCommand {
|
|
|
61
56
|
public setNsfw(nsfw = true): this {
|
|
62
57
|
return this.setNSFW(nsfw);
|
|
63
58
|
}
|
|
64
|
-
/** Sets command default member permissions. */
|
|
59
|
+
/** Sets command default member permissions. */
|
|
60
|
+
public setDefaultMemberPermissions(
|
|
65
61
|
permissions: bigint | number | string | null,
|
|
66
62
|
): this {
|
|
67
63
|
this.#data.default_member_permissions =
|
|
68
64
|
permissions === null ? null : BigInt(permissions).toString();
|
|
69
65
|
return this;
|
|
70
66
|
}
|
|
71
|
-
/** Sets command integration types. */
|
|
72
|
-
|
|
73
|
-
): this {
|
|
67
|
+
/** Sets command integration types. */
|
|
68
|
+
public setIntegrationTypes(...types: number[]): this {
|
|
74
69
|
this.#data.integration_types = [...types];
|
|
75
70
|
return this;
|
|
76
71
|
}
|
|
77
|
-
/** Adds a string option. */
|
|
72
|
+
/** Adds a string option. */
|
|
73
|
+
public addStringOption(
|
|
78
74
|
configure: (option: CreateStringOption) => CreateStringOption,
|
|
79
75
|
): this {
|
|
80
76
|
return this.addOption(configure(new CreateStringOption()));
|
|
81
77
|
}
|
|
82
|
-
/** Adds an integer option. */
|
|
78
|
+
/** Adds an integer option. */
|
|
79
|
+
public addIntegerOption(
|
|
83
80
|
configure: (option: CreateIntegerOption) => CreateIntegerOption,
|
|
84
81
|
): this {
|
|
85
82
|
return this.addOption(configure(new CreateIntegerOption()));
|
|
86
83
|
}
|
|
87
|
-
/** Adds a number option. */
|
|
84
|
+
/** Adds a number option. */
|
|
85
|
+
public addNumberOption(
|
|
88
86
|
configure: (option: CreateNumberOption) => CreateNumberOption,
|
|
89
87
|
): this {
|
|
90
88
|
return this.addOption(configure(new CreateNumberOption()));
|
|
91
89
|
}
|
|
92
|
-
/** Adds a boolean option. */
|
|
90
|
+
/** Adds a boolean option. */
|
|
91
|
+
public addBooleanOption(
|
|
93
92
|
configure: (option: CreateBooleanOption) => CreateBooleanOption,
|
|
94
93
|
): this {
|
|
95
94
|
return this.addOption(configure(new CreateBooleanOption()));
|
|
96
95
|
}
|
|
97
|
-
/** Adds a user option. */
|
|
96
|
+
/** Adds a user option. */
|
|
97
|
+
public addUserOption(
|
|
98
98
|
configure: (option: CreateUserOption) => CreateUserOption,
|
|
99
99
|
): this {
|
|
100
100
|
return this.addOption(configure(new CreateUserOption()));
|
|
101
101
|
}
|
|
102
|
-
/** Adds a channel option. */
|
|
102
|
+
/** Adds a channel option. */
|
|
103
|
+
public addChannelOption(
|
|
103
104
|
configure: (option: CreateChannelOption) => CreateChannelOption,
|
|
104
105
|
): this {
|
|
105
106
|
return this.addOption(configure(new CreateChannelOption()));
|
|
106
107
|
}
|
|
107
|
-
/** Adds a role option. */
|
|
108
|
+
/** Adds a role option. */
|
|
109
|
+
public addRoleOption(
|
|
108
110
|
configure: (option: CreateRoleOption) => CreateRoleOption,
|
|
109
111
|
): this {
|
|
110
112
|
return this.addOption(configure(new CreateRoleOption()));
|
|
111
113
|
}
|
|
112
|
-
/** Adds a mentionable option. */
|
|
114
|
+
/** Adds a mentionable option. */
|
|
115
|
+
public addMentionableOption(
|
|
113
116
|
configure: (option: CreateMentionableOption) => CreateMentionableOption,
|
|
114
117
|
): this {
|
|
115
118
|
return this.addOption(configure(new CreateMentionableOption()));
|
|
116
119
|
}
|
|
117
|
-
/** Adds an attachment option. */
|
|
120
|
+
/** Adds an attachment option. */
|
|
121
|
+
public addAttachmentOption(
|
|
118
122
|
configure: (option: CreateAttachmentOption) => CreateAttachmentOption,
|
|
119
123
|
): this {
|
|
120
124
|
return this.addOption(configure(new CreateAttachmentOption()));
|
|
121
125
|
}
|
|
122
|
-
/** Adds a subcommand. */
|
|
126
|
+
/** Adds a subcommand. */
|
|
127
|
+
public addSubcommand(
|
|
123
128
|
configure: (option: CreateSubcommand) => CreateSubcommand,
|
|
124
129
|
): this {
|
|
125
130
|
return this.addOption(configure(new CreateSubcommand()));
|
|
126
131
|
}
|
|
127
|
-
/** Adds a subcommand group. */
|
|
132
|
+
/** Adds a subcommand group. */
|
|
133
|
+
public addSubcommandGroup(
|
|
128
134
|
configure: (option: CreateSubcommandGroup) => CreateSubcommandGroup,
|
|
129
135
|
): this {
|
|
130
136
|
return this.addOption(configure(new CreateSubcommandGroup()));
|
|
131
137
|
}
|
|
132
|
-
/** Serializes the command payload. */
|
|
133
|
-
|
|
134
|
-
unknown
|
|
135
|
-
> {
|
|
138
|
+
/** Serializes the command payload. */
|
|
139
|
+
public toJSON(): Record<string, unknown> {
|
|
136
140
|
return structuredClone(this.#data);
|
|
137
141
|
}
|
|
138
|
-
/** Adds a validated top-level command option. */
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
);
|
|
146
|
-
const payload = option.toJSON();
|
|
147
|
-
if (
|
|
148
|
-
options.some(
|
|
149
|
-
(existing) =>
|
|
150
|
-
(existing as Record<string, unknown>).name === payload.name,
|
|
151
|
-
)
|
|
152
|
-
)
|
|
153
|
-
throw new RangeError(
|
|
154
|
-
`Duplicate option name: ${String(payload.name)}.`,
|
|
155
|
-
);
|
|
156
|
-
if (
|
|
157
|
-
payload.required === true &&
|
|
158
|
-
options.some(
|
|
159
|
-
(existing) =>
|
|
160
|
-
(existing as Record<string, unknown>).required !== true,
|
|
161
|
-
)
|
|
162
|
-
)
|
|
163
|
-
throw new RangeError(
|
|
164
|
-
"Required application command options must be placed before optional options.",
|
|
165
|
-
);
|
|
166
|
-
options.push(payload);
|
|
167
|
-
this.#data.options = options;
|
|
142
|
+
/** Adds a validated top-level command option. */
|
|
143
|
+
protected addOption(option: CreateCommandOption): this {
|
|
144
|
+
this.#data.options = appendOption(
|
|
145
|
+
this.#data.options,
|
|
146
|
+
option.toJSON(),
|
|
147
|
+
"application command",
|
|
148
|
+
);
|
|
168
149
|
return this;
|
|
169
150
|
}
|
|
170
151
|
}
|
|
@@ -172,76 +153,61 @@ export class CreateSlashCommand {
|
|
|
172
153
|
/** Base builder for command options. */
|
|
173
154
|
export class CreateCommandOption {
|
|
174
155
|
protected readonly data: Record<string, unknown>;
|
|
175
|
-
/** Creates an option builder. */
|
|
156
|
+
/** Creates an option builder. */
|
|
157
|
+
public constructor(type: number) {
|
|
176
158
|
this.data = { type };
|
|
177
159
|
}
|
|
178
|
-
/** Sets the option name. */
|
|
160
|
+
/** Sets the option name. */
|
|
161
|
+
public setName(name: string): this {
|
|
179
162
|
validateName(name, "Option name");
|
|
180
163
|
this.data.name = name;
|
|
181
164
|
return this;
|
|
182
165
|
}
|
|
183
|
-
/** Sets the option description. */
|
|
184
|
-
|
|
185
|
-
): this {
|
|
166
|
+
/** Sets the option description. */
|
|
167
|
+
public setDescription(description: string): this {
|
|
186
168
|
validateText(description, "Option description", 100);
|
|
187
169
|
this.data.description = description;
|
|
188
170
|
return this;
|
|
189
171
|
}
|
|
190
|
-
/** Makes the option required or optional. */
|
|
191
|
-
|
|
192
|
-
): this {
|
|
172
|
+
/** Makes the option required or optional. */
|
|
173
|
+
public setRequired(required = true): this {
|
|
193
174
|
this.data.required = required;
|
|
194
175
|
return this;
|
|
195
176
|
}
|
|
196
|
-
/** Sets autocomplete. */
|
|
177
|
+
/** Sets autocomplete. */
|
|
178
|
+
public setAutocomplete(enabled = true): this {
|
|
197
179
|
this.data.autocomplete = enabled;
|
|
198
180
|
return this;
|
|
199
181
|
}
|
|
200
|
-
/** Serializes the option payload. */
|
|
201
|
-
|
|
202
|
-
unknown
|
|
203
|
-
> {
|
|
182
|
+
/** Serializes the option payload. */
|
|
183
|
+
public toJSON(): Record<string, unknown> {
|
|
204
184
|
return structuredClone(this.data);
|
|
205
185
|
}
|
|
206
186
|
}
|
|
207
187
|
|
|
208
188
|
/** Builds a string command option. */
|
|
209
189
|
export class CreateStringOption extends CreateCommandOption {
|
|
210
|
-
/** Creates a string option. */
|
|
190
|
+
/** Creates a string option. */
|
|
191
|
+
public constructor() {
|
|
211
192
|
super(ApplicationCommandOptionEnum.String);
|
|
212
193
|
}
|
|
213
|
-
/** Adds string choices. */
|
|
194
|
+
/** Adds string choices. */
|
|
195
|
+
public addChoices(
|
|
214
196
|
...choices: Array<{ name: string; value: string }>
|
|
215
197
|
): this {
|
|
216
|
-
const
|
|
217
|
-
if (!choices.length)
|
|
218
|
-
throw new TypeError("At least one choice is required.");
|
|
219
|
-
if (this.data.autocomplete === true)
|
|
220
|
-
throw new RangeError("Autocomplete options cannot define choices.");
|
|
221
|
-
if (current.length + choices.length > 25)
|
|
222
|
-
throw new RangeError(
|
|
223
|
-
"An option cannot contain more than 25 choices.",
|
|
224
|
-
);
|
|
225
|
-
for (const choice of choices) {
|
|
226
|
-
validateText(choice.name, "Choice name", 100);
|
|
198
|
+
for (const choice of choices)
|
|
227
199
|
validateText(choice.value, "Choice value", 100);
|
|
228
|
-
|
|
229
|
-
this.data.choices = [
|
|
230
|
-
...current,
|
|
231
|
-
...choices.map((choice) => ({ ...choice })),
|
|
232
|
-
];
|
|
200
|
+
appendChoices(this.data, choices);
|
|
233
201
|
return this;
|
|
234
202
|
}
|
|
235
|
-
/** Sets the minimum string length. */
|
|
236
|
-
|
|
237
|
-
): this {
|
|
203
|
+
/** Sets the minimum string length. */
|
|
204
|
+
public setMinLength(value: number): this {
|
|
238
205
|
validateIntegerRange(value, 0, 6000, "min_length");
|
|
239
206
|
this.data.min_length = value;
|
|
240
207
|
return this;
|
|
241
208
|
}
|
|
242
|
-
/** Sets the maximum string length. */
|
|
243
|
-
|
|
244
|
-
): this {
|
|
209
|
+
/** Sets the maximum string length. */
|
|
210
|
+
public setMaxLength(value: number): this {
|
|
245
211
|
validateIntegerRange(value, 1, 6000, "max_length");
|
|
246
212
|
if (
|
|
247
213
|
(this.data.min_length as number | undefined) !== undefined &&
|
|
@@ -252,38 +218,42 @@ export class CreateStringOption extends CreateCommandOption {
|
|
|
252
218
|
return this;
|
|
253
219
|
}
|
|
254
220
|
}
|
|
255
|
-
/**
|
|
256
|
-
export class
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
221
|
+
/** Shared bounds, choices and autocomplete rules of integer and number options. */
|
|
222
|
+
export class CreateNumericOption extends CreateCommandOption {
|
|
223
|
+
readonly #integer: boolean;
|
|
224
|
+
/** Creates a numeric option; `integer` rejects fractional bounds. */
|
|
225
|
+
public constructor(type: number, integer: boolean) {
|
|
226
|
+
super(type);
|
|
227
|
+
this.#integer = integer;
|
|
228
|
+
}
|
|
229
|
+
/** Sets the minimum value. */
|
|
260
230
|
public setMinValue(value: number): this {
|
|
261
231
|
validateNumberRange(
|
|
262
232
|
value,
|
|
263
|
-
-
|
|
264
|
-
|
|
233
|
+
-MAX_SAFE,
|
|
234
|
+
MAX_SAFE,
|
|
265
235
|
"min_value",
|
|
266
|
-
|
|
236
|
+
this.#integer,
|
|
267
237
|
);
|
|
268
238
|
this.data.min_value = value;
|
|
269
239
|
return this;
|
|
270
240
|
}
|
|
241
|
+
/** Sets the maximum value; it cannot be below the minimum. */
|
|
271
242
|
public setMaxValue(value: number): this {
|
|
272
243
|
validateNumberRange(
|
|
273
244
|
value,
|
|
274
|
-
-
|
|
275
|
-
|
|
245
|
+
-MAX_SAFE,
|
|
246
|
+
MAX_SAFE,
|
|
276
247
|
"max_value",
|
|
277
|
-
|
|
248
|
+
this.#integer,
|
|
278
249
|
);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
(this.data.min_value as number) > value
|
|
282
|
-
)
|
|
250
|
+
const min = this.data.min_value as number | undefined;
|
|
251
|
+
if (min !== undefined && min > value)
|
|
283
252
|
throw new RangeError("min_value cannot exceed max_value.");
|
|
284
253
|
this.data.max_value = value;
|
|
285
254
|
return this;
|
|
286
255
|
}
|
|
256
|
+
/** Enables autocomplete; options with choices cannot use it. */
|
|
287
257
|
public override setAutocomplete(enabled = true): this {
|
|
288
258
|
if (
|
|
289
259
|
enabled &&
|
|
@@ -294,108 +264,67 @@ export class CreateIntegerOption extends CreateCommandOption {
|
|
|
294
264
|
this.data.autocomplete = enabled;
|
|
295
265
|
return this;
|
|
296
266
|
}
|
|
267
|
+
/** Adds fixed choices. */
|
|
297
268
|
public addChoices(...choices: { name: string; value: number }[]): this {
|
|
298
|
-
|
|
299
|
-
if (!choices.length)
|
|
300
|
-
throw new TypeError("At least one choice is required.");
|
|
301
|
-
if (this.data.autocomplete === true)
|
|
302
|
-
throw new RangeError("Autocomplete options cannot define choices.");
|
|
303
|
-
if (current.length + choices.length > 25)
|
|
304
|
-
throw new RangeError(
|
|
305
|
-
"An option cannot contain more than 25 choices.",
|
|
306
|
-
);
|
|
307
|
-
this.data.choices = [...current, ...choices];
|
|
269
|
+
appendChoices(this.data, choices);
|
|
308
270
|
return this;
|
|
309
271
|
}
|
|
310
272
|
}
|
|
311
|
-
/** Builds
|
|
312
|
-
export class
|
|
273
|
+
/** Builds an integer command option. */
|
|
274
|
+
export class CreateIntegerOption extends CreateNumericOption {
|
|
313
275
|
public constructor() {
|
|
314
|
-
super(ApplicationCommandOptionEnum.
|
|
315
|
-
}
|
|
316
|
-
public setMinValue(value: number): this {
|
|
317
|
-
validateNumberRange(
|
|
318
|
-
value,
|
|
319
|
-
-9_007_199_254_740_991,
|
|
320
|
-
9_007_199_254_740_991,
|
|
321
|
-
"min_value",
|
|
322
|
-
false,
|
|
323
|
-
);
|
|
324
|
-
this.data.min_value = value;
|
|
325
|
-
return this;
|
|
276
|
+
super(ApplicationCommandOptionEnum.Integer, true);
|
|
326
277
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
"max_value",
|
|
333
|
-
false,
|
|
334
|
-
);
|
|
335
|
-
if (
|
|
336
|
-
(this.data.min_value as number | undefined) !== undefined &&
|
|
337
|
-
(this.data.min_value as number) > value
|
|
338
|
-
)
|
|
339
|
-
throw new RangeError("min_value cannot exceed max_value.");
|
|
340
|
-
this.data.max_value = value;
|
|
341
|
-
return this;
|
|
342
|
-
}
|
|
343
|
-
public override setAutocomplete(enabled = true): this {
|
|
344
|
-
if (
|
|
345
|
-
enabled &&
|
|
346
|
-
Array.isArray(this.data.choices) &&
|
|
347
|
-
this.data.choices.length
|
|
348
|
-
)
|
|
349
|
-
throw new RangeError("Autocomplete options cannot define choices.");
|
|
350
|
-
this.data.autocomplete = enabled;
|
|
351
|
-
return this;
|
|
352
|
-
}
|
|
353
|
-
public addChoices(...choices: { name: string; value: number }[]): this {
|
|
354
|
-
const current = (this.data.choices as unknown[] | undefined) ?? [];
|
|
355
|
-
if (!choices.length)
|
|
356
|
-
throw new TypeError("At least one choice is required.");
|
|
357
|
-
if (this.data.autocomplete === true)
|
|
358
|
-
throw new RangeError("Autocomplete options cannot define choices.");
|
|
359
|
-
if (current.length + choices.length > 25)
|
|
360
|
-
throw new RangeError(
|
|
361
|
-
"An option cannot contain more than 25 choices.",
|
|
362
|
-
);
|
|
363
|
-
this.data.choices = [...current, ...choices];
|
|
364
|
-
return this;
|
|
278
|
+
}
|
|
279
|
+
/** Builds a number command option. */
|
|
280
|
+
export class CreateNumberOption extends CreateNumericOption {
|
|
281
|
+
public constructor() {
|
|
282
|
+
super(ApplicationCommandOptionEnum.Number, false);
|
|
365
283
|
}
|
|
366
284
|
}
|
|
367
|
-
/** Builds a boolean command option. */
|
|
368
|
-
|
|
285
|
+
/** Builds a boolean command option. */
|
|
286
|
+
export class CreateBooleanOption extends CreateCommandOption {
|
|
287
|
+
/** Creates a boolean option. */
|
|
288
|
+
public constructor() {
|
|
369
289
|
super(ApplicationCommandOptionEnum.Boolean);
|
|
370
290
|
}
|
|
371
291
|
}
|
|
372
|
-
/** Builds a user command option. */
|
|
373
|
-
|
|
292
|
+
/** Builds a user command option. */
|
|
293
|
+
export class CreateUserOption extends CreateCommandOption {
|
|
294
|
+
/** Creates a user option. */
|
|
295
|
+
public constructor() {
|
|
374
296
|
super(ApplicationCommandOptionEnum.User);
|
|
375
297
|
}
|
|
376
298
|
}
|
|
377
|
-
/** Builds a role command option. */
|
|
378
|
-
|
|
299
|
+
/** Builds a role command option. */
|
|
300
|
+
export class CreateRoleOption extends CreateCommandOption {
|
|
301
|
+
/** Creates a role option. */
|
|
302
|
+
public constructor() {
|
|
379
303
|
super(ApplicationCommandOptionEnum.Role);
|
|
380
304
|
}
|
|
381
305
|
}
|
|
382
|
-
/** Builds a mentionable command option. */
|
|
383
|
-
|
|
306
|
+
/** Builds a mentionable command option. */
|
|
307
|
+
export class CreateMentionableOption extends CreateCommandOption {
|
|
308
|
+
/** Creates a mentionable option. */
|
|
309
|
+
public constructor() {
|
|
384
310
|
super(ApplicationCommandOptionEnum.Mentionable);
|
|
385
311
|
}
|
|
386
312
|
}
|
|
387
|
-
/** Builds an attachment command option. */
|
|
388
|
-
|
|
313
|
+
/** Builds an attachment command option. */
|
|
314
|
+
export class CreateAttachmentOption extends CreateCommandOption {
|
|
315
|
+
/** Creates an attachment option. */
|
|
316
|
+
public constructor() {
|
|
389
317
|
super(ApplicationCommandOptionEnum.Attachment);
|
|
390
318
|
}
|
|
391
319
|
}
|
|
392
|
-
/** Builds a channel command option. */
|
|
393
|
-
|
|
320
|
+
/** Builds a channel command option. */
|
|
321
|
+
export class CreateChannelOption extends CreateCommandOption {
|
|
322
|
+
/** Creates a channel option. */
|
|
323
|
+
public constructor() {
|
|
394
324
|
super(ApplicationCommandOptionEnum.Channel);
|
|
395
325
|
}
|
|
396
|
-
/** Restricts accepted channel types. */
|
|
397
|
-
|
|
398
|
-
): this {
|
|
326
|
+
/** Restricts accepted channel types. */
|
|
327
|
+
public addChannelTypes(...types: number[]): this {
|
|
399
328
|
if (types.some((type) => !Number.isInteger(type) || type < 0))
|
|
400
329
|
throw new RangeError(
|
|
401
330
|
"Channel types must be non-negative integers.",
|
|
@@ -404,101 +333,94 @@ export class CreateNumberOption extends CreateCommandOption {
|
|
|
404
333
|
return this;
|
|
405
334
|
}
|
|
406
335
|
}
|
|
407
|
-
/** Builds a nested subcommand. */
|
|
408
|
-
|
|
336
|
+
/** Builds a nested subcommand. */
|
|
337
|
+
export class CreateSubcommand extends CreateCommandOption {
|
|
338
|
+
/** Creates a subcommand. */
|
|
339
|
+
public constructor() {
|
|
409
340
|
super(ApplicationCommandOptionEnum.Subcommand);
|
|
410
341
|
}
|
|
411
|
-
/** Adds a string option to this subcommand. */
|
|
342
|
+
/** Adds a string option to this subcommand. */
|
|
343
|
+
public addStringOption(
|
|
412
344
|
configure: (option: CreateStringOption) => CreateStringOption,
|
|
413
345
|
): this {
|
|
414
346
|
return this.addChildOption(configure(new CreateStringOption()));
|
|
415
347
|
}
|
|
416
|
-
/** Adds an integer option to this subcommand. */
|
|
348
|
+
/** Adds an integer option to this subcommand. */
|
|
349
|
+
public addIntegerOption(
|
|
417
350
|
configure: (option: CreateIntegerOption) => CreateIntegerOption,
|
|
418
351
|
): this {
|
|
419
352
|
return this.addChildOption(configure(new CreateIntegerOption()));
|
|
420
353
|
}
|
|
421
|
-
/** Adds a number option to this subcommand. */
|
|
354
|
+
/** Adds a number option to this subcommand. */
|
|
355
|
+
public addNumberOption(
|
|
422
356
|
configure: (option: CreateNumberOption) => CreateNumberOption,
|
|
423
357
|
): this {
|
|
424
358
|
return this.addChildOption(configure(new CreateNumberOption()));
|
|
425
359
|
}
|
|
426
|
-
/** Adds a boolean option to this subcommand. */
|
|
360
|
+
/** Adds a boolean option to this subcommand. */
|
|
361
|
+
public addBooleanOption(
|
|
427
362
|
configure: (option: CreateBooleanOption) => CreateBooleanOption,
|
|
428
363
|
): this {
|
|
429
364
|
return this.addChildOption(configure(new CreateBooleanOption()));
|
|
430
365
|
}
|
|
431
|
-
/** Adds a user option to this subcommand. */
|
|
366
|
+
/** Adds a user option to this subcommand. */
|
|
367
|
+
public addUserOption(
|
|
432
368
|
configure: (option: CreateUserOption) => CreateUserOption,
|
|
433
369
|
): this {
|
|
434
370
|
return this.addChildOption(configure(new CreateUserOption()));
|
|
435
371
|
}
|
|
436
|
-
/** Adds a channel option to this subcommand. */
|
|
372
|
+
/** Adds a channel option to this subcommand. */
|
|
373
|
+
public addChannelOption(
|
|
437
374
|
configure: (option: CreateChannelOption) => CreateChannelOption,
|
|
438
375
|
): this {
|
|
439
376
|
return this.addChildOption(configure(new CreateChannelOption()));
|
|
440
377
|
}
|
|
441
|
-
/** Adds a role option to this subcommand. */
|
|
378
|
+
/** Adds a role option to this subcommand. */
|
|
379
|
+
public addRoleOption(
|
|
442
380
|
configure: (option: CreateRoleOption) => CreateRoleOption,
|
|
443
381
|
): this {
|
|
444
382
|
return this.addChildOption(configure(new CreateRoleOption()));
|
|
445
383
|
}
|
|
446
|
-
/** Adds a mentionable option to this subcommand. */
|
|
384
|
+
/** Adds a mentionable option to this subcommand. */
|
|
385
|
+
public addMentionableOption(
|
|
447
386
|
configure: (option: CreateMentionableOption) => CreateMentionableOption,
|
|
448
387
|
): this {
|
|
449
388
|
return this.addChildOption(configure(new CreateMentionableOption()));
|
|
450
389
|
}
|
|
451
|
-
/** Adds an attachment option to this subcommand. */
|
|
390
|
+
/** Adds an attachment option to this subcommand. */
|
|
391
|
+
public addAttachmentOption(
|
|
452
392
|
configure: (option: CreateAttachmentOption) => CreateAttachmentOption,
|
|
453
393
|
): this {
|
|
454
394
|
return this.addChildOption(configure(new CreateAttachmentOption()));
|
|
455
395
|
}
|
|
456
396
|
protected addChildOption(option: CreateCommandOption): this {
|
|
457
|
-
const options =
|
|
458
|
-
|
|
459
|
-
throw new RangeError(
|
|
460
|
-
"A subcommand cannot contain more than 25 options.",
|
|
461
|
-
);
|
|
462
|
-
const payload = option.toJSON();
|
|
397
|
+
const options =
|
|
398
|
+
(this.data.options as OptionPayload[] | undefined) ?? [];
|
|
463
399
|
if (
|
|
464
400
|
options.some(
|
|
465
401
|
(existing) =>
|
|
466
|
-
|
|
467
|
-
)
|
|
468
|
-
)
|
|
469
|
-
throw new RangeError(
|
|
470
|
-
`Duplicate option name: ${String(payload.name)}.`,
|
|
471
|
-
);
|
|
472
|
-
if (
|
|
473
|
-
payload.required === true &&
|
|
474
|
-
options.some(
|
|
475
|
-
(existing) =>
|
|
476
|
-
(existing as Record<string, unknown>).required !== true,
|
|
477
|
-
)
|
|
478
|
-
)
|
|
479
|
-
throw new RangeError(
|
|
480
|
-
"Required subcommand options must be placed before optional options.",
|
|
481
|
-
);
|
|
482
|
-
if (
|
|
483
|
-
options.some(
|
|
484
|
-
(existing) =>
|
|
485
|
-
(existing as Record<string, unknown>).type ===
|
|
486
|
-
ApplicationCommandOptionEnum.Subcommand,
|
|
402
|
+
existing.type === ApplicationCommandOptionEnum.Subcommand,
|
|
487
403
|
)
|
|
488
404
|
)
|
|
489
405
|
throw new RangeError(
|
|
490
406
|
"Subcommands cannot contain nested subcommands.",
|
|
491
407
|
);
|
|
492
|
-
options
|
|
493
|
-
|
|
408
|
+
this.data.options = appendOption(
|
|
409
|
+
options,
|
|
410
|
+
option.toJSON(),
|
|
411
|
+
"subcommand",
|
|
412
|
+
);
|
|
494
413
|
return this;
|
|
495
414
|
}
|
|
496
415
|
}
|
|
497
|
-
/** Builds a nested subcommand group. */
|
|
498
|
-
|
|
416
|
+
/** Builds a nested subcommand group. */
|
|
417
|
+
export class CreateSubcommandGroup extends CreateCommandOption {
|
|
418
|
+
/** Creates a subcommand group. */
|
|
419
|
+
public constructor() {
|
|
499
420
|
super(ApplicationCommandOptionEnum.SubcommandGroup);
|
|
500
421
|
}
|
|
501
|
-
/** Adds a subcommand to this group. */
|
|
422
|
+
/** Adds a subcommand to this group. */
|
|
423
|
+
public addSubcommand(
|
|
502
424
|
configure: (option: CreateSubcommand) => CreateSubcommand,
|
|
503
425
|
): this {
|
|
504
426
|
const options = (this.data.options as unknown[] | undefined) ?? [];
|
|
@@ -525,6 +447,53 @@ export class CreateNumberOption extends CreateCommandOption {
|
|
|
525
447
|
return this;
|
|
526
448
|
}
|
|
527
449
|
}
|
|
450
|
+
const MAX_SAFE = Number.MAX_SAFE_INTEGER;
|
|
451
|
+
|
|
452
|
+
/** A serialized option as stored on its parent. */
|
|
453
|
+
type OptionPayload = Record<string, unknown>;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Returns `options` with `payload` appended, enforcing Discord's limit of 25,
|
|
457
|
+
* unique names, and required options before optional ones.
|
|
458
|
+
*/
|
|
459
|
+
function appendOption(
|
|
460
|
+
options: unknown,
|
|
461
|
+
payload: OptionPayload,
|
|
462
|
+
parent: "application command" | "subcommand",
|
|
463
|
+
): OptionPayload[] {
|
|
464
|
+
const list = (options as OptionPayload[] | undefined) ?? [];
|
|
465
|
+
if (list.length >= 25)
|
|
466
|
+
throw new RangeError(
|
|
467
|
+
`${parent === "subcommand" ? "A subcommand" : "An application command"} cannot contain more than 25 options.`,
|
|
468
|
+
);
|
|
469
|
+
if (list.some((existing) => existing.name === payload.name))
|
|
470
|
+
throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);
|
|
471
|
+
if (
|
|
472
|
+
payload.required === true &&
|
|
473
|
+
list.some((existing) => existing.required !== true)
|
|
474
|
+
)
|
|
475
|
+
throw new RangeError(
|
|
476
|
+
`Required ${parent} options must be placed before optional options.`,
|
|
477
|
+
);
|
|
478
|
+
return [...list, payload];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/** Appends choices to an option, enforcing the shared choice rules. */
|
|
482
|
+
function appendChoices(
|
|
483
|
+
data: OptionPayload,
|
|
484
|
+
choices: { name: string; value: string | number }[],
|
|
485
|
+
): void {
|
|
486
|
+
const current = (data.choices as unknown[] | undefined) ?? [];
|
|
487
|
+
if (!choices.length)
|
|
488
|
+
throw new TypeError("At least one choice is required.");
|
|
489
|
+
if (data.autocomplete === true)
|
|
490
|
+
throw new RangeError("Autocomplete options cannot define choices.");
|
|
491
|
+
if (current.length + choices.length > 25)
|
|
492
|
+
throw new RangeError("An option cannot contain more than 25 choices.");
|
|
493
|
+
for (const choice of choices) validateText(choice.name, "Choice name", 100);
|
|
494
|
+
data.choices = [...current, ...choices.map((choice) => ({ ...choice }))];
|
|
495
|
+
}
|
|
496
|
+
|
|
528
497
|
function validateName(value: string, field: string): void {
|
|
529
498
|
if (!/^[\p{L}\p{N}_-]{1,32}$/u.test(value) || value !== value.toLowerCase())
|
|
530
499
|
throw new RangeError(
|
|
@@ -606,11 +575,6 @@ export class CreateContextMenuCommand {
|
|
|
606
575
|
permissions === null ? null : BigInt(permissions).toString();
|
|
607
576
|
return this;
|
|
608
577
|
}
|
|
609
|
-
/** @deprecated Discord deprecated `dm_permission`. Use {@link CreateContextMenuCommand.setContexts}: `setContexts(0)` for guilds only, `setContexts(0, 1)` to allow the bot's DMs. Removed in 0.3.0. */
|
|
610
|
-
public setDMPermission(enabled: boolean): this {
|
|
611
|
-
this.data.dm_permission = enabled;
|
|
612
|
-
return this;
|
|
613
|
-
}
|
|
614
578
|
/** Sets command integration types (0 guild install, 1 user install). */
|
|
615
579
|
public setIntegrationTypes(...types: number[]): this {
|
|
616
580
|
this.data.integration_types = [...types];
|
|
@@ -655,92 +619,3 @@ export class CreateMessageCommand extends CreateContextMenuCommand {
|
|
|
655
619
|
super(3);
|
|
656
620
|
}
|
|
657
621
|
}
|
|
658
|
-
|
|
659
|
-
// ─── Deprecated names (0.2.2), removed in 0.3.0 ────────────────────────────────
|
|
660
|
-
// Builders are now `CreateX` (`ButtonBuilder` → `CreateButton`); `…Style` became
|
|
661
|
-
// `…Type` and `…Type` became `…Enum`.
|
|
662
|
-
|
|
663
|
-
/** @deprecated Use {@link CreateAttachmentOption}. Removed in 0.3.0. */
|
|
664
|
-
export const AttachmentOptionBuilder = CreateAttachmentOption;
|
|
665
|
-
/** @deprecated Use {@link CreateAttachmentOption}. Removed in 0.3.0. */
|
|
666
|
-
export type AttachmentOptionBuilder = CreateAttachmentOption;
|
|
667
|
-
|
|
668
|
-
/** @deprecated Use {@link CreateBooleanOption}. Removed in 0.3.0. */
|
|
669
|
-
export const BooleanOptionBuilder = CreateBooleanOption;
|
|
670
|
-
/** @deprecated Use {@link CreateBooleanOption}. Removed in 0.3.0. */
|
|
671
|
-
export type BooleanOptionBuilder = CreateBooleanOption;
|
|
672
|
-
|
|
673
|
-
/** @deprecated Use {@link CreateChannelOption}. Removed in 0.3.0. */
|
|
674
|
-
export const ChannelOptionBuilder = CreateChannelOption;
|
|
675
|
-
/** @deprecated Use {@link CreateChannelOption}. Removed in 0.3.0. */
|
|
676
|
-
export type ChannelOptionBuilder = CreateChannelOption;
|
|
677
|
-
|
|
678
|
-
/** @deprecated Use {@link CreateCommandOption}. Removed in 0.3.0. */
|
|
679
|
-
export const CommandOptionBuilder = CreateCommandOption;
|
|
680
|
-
/** @deprecated Use {@link CreateCommandOption}. Removed in 0.3.0. */
|
|
681
|
-
export type CommandOptionBuilder = CreateCommandOption;
|
|
682
|
-
|
|
683
|
-
/** @deprecated Use {@link CreateContextMenuCommand}. Removed in 0.3.0. */
|
|
684
|
-
export const ContextMenuCommandBuilder = CreateContextMenuCommand;
|
|
685
|
-
/** @deprecated Use {@link CreateContextMenuCommand}. Removed in 0.3.0. */
|
|
686
|
-
export type ContextMenuCommandBuilder = CreateContextMenuCommand;
|
|
687
|
-
|
|
688
|
-
/** @deprecated Use {@link CreateIntegerOption}. Removed in 0.3.0. */
|
|
689
|
-
export const IntegerOptionBuilder = CreateIntegerOption;
|
|
690
|
-
/** @deprecated Use {@link CreateIntegerOption}. Removed in 0.3.0. */
|
|
691
|
-
export type IntegerOptionBuilder = CreateIntegerOption;
|
|
692
|
-
|
|
693
|
-
/** @deprecated Use {@link CreateMentionableOption}. Removed in 0.3.0. */
|
|
694
|
-
export const MentionableOptionBuilder = CreateMentionableOption;
|
|
695
|
-
/** @deprecated Use {@link CreateMentionableOption}. Removed in 0.3.0. */
|
|
696
|
-
export type MentionableOptionBuilder = CreateMentionableOption;
|
|
697
|
-
|
|
698
|
-
/** @deprecated Use {@link CreateMessageCommand}. Removed in 0.3.0. */
|
|
699
|
-
export const MessageCommandBuilder = CreateMessageCommand;
|
|
700
|
-
/** @deprecated Use {@link CreateMessageCommand}. Removed in 0.3.0. */
|
|
701
|
-
export type MessageCommandBuilder = CreateMessageCommand;
|
|
702
|
-
|
|
703
|
-
/** @deprecated Use {@link CreateNumberOption}. Removed in 0.3.0. */
|
|
704
|
-
export const NumberOptionBuilder = CreateNumberOption;
|
|
705
|
-
/** @deprecated Use {@link CreateNumberOption}. Removed in 0.3.0. */
|
|
706
|
-
export type NumberOptionBuilder = CreateNumberOption;
|
|
707
|
-
|
|
708
|
-
/** @deprecated Use {@link CreateRoleOption}. Removed in 0.3.0. */
|
|
709
|
-
export const RoleOptionBuilder = CreateRoleOption;
|
|
710
|
-
/** @deprecated Use {@link CreateRoleOption}. Removed in 0.3.0. */
|
|
711
|
-
export type RoleOptionBuilder = CreateRoleOption;
|
|
712
|
-
|
|
713
|
-
/** @deprecated Use {@link CreateSlashCommand}. Removed in 0.3.0. */
|
|
714
|
-
export const SlashCommandBuilder = CreateSlashCommand;
|
|
715
|
-
/** @deprecated Use {@link CreateSlashCommand}. Removed in 0.3.0. */
|
|
716
|
-
export type SlashCommandBuilder = CreateSlashCommand;
|
|
717
|
-
|
|
718
|
-
/** @deprecated Use {@link CreateStringOption}. Removed in 0.3.0. */
|
|
719
|
-
export const StringOptionBuilder = CreateStringOption;
|
|
720
|
-
/** @deprecated Use {@link CreateStringOption}. Removed in 0.3.0. */
|
|
721
|
-
export type StringOptionBuilder = CreateStringOption;
|
|
722
|
-
|
|
723
|
-
/** @deprecated Use {@link CreateSubcommand}. Removed in 0.3.0. */
|
|
724
|
-
export const SubcommandBuilder = CreateSubcommand;
|
|
725
|
-
/** @deprecated Use {@link CreateSubcommand}. Removed in 0.3.0. */
|
|
726
|
-
export type SubcommandBuilder = CreateSubcommand;
|
|
727
|
-
|
|
728
|
-
/** @deprecated Use {@link CreateSubcommandGroup}. Removed in 0.3.0. */
|
|
729
|
-
export const SubcommandGroupBuilder = CreateSubcommandGroup;
|
|
730
|
-
/** @deprecated Use {@link CreateSubcommandGroup}. Removed in 0.3.0. */
|
|
731
|
-
export type SubcommandGroupBuilder = CreateSubcommandGroup;
|
|
732
|
-
|
|
733
|
-
/** @deprecated Use {@link CreateUserCommand}. Removed in 0.3.0. */
|
|
734
|
-
export const UserCommandBuilder = CreateUserCommand;
|
|
735
|
-
/** @deprecated Use {@link CreateUserCommand}. Removed in 0.3.0. */
|
|
736
|
-
export type UserCommandBuilder = CreateUserCommand;
|
|
737
|
-
|
|
738
|
-
/** @deprecated Use {@link CreateUserOption}. Removed in 0.3.0. */
|
|
739
|
-
export const UserOptionBuilder = CreateUserOption;
|
|
740
|
-
/** @deprecated Use {@link CreateUserOption}. Removed in 0.3.0. */
|
|
741
|
-
export type UserOptionBuilder = CreateUserOption;
|
|
742
|
-
|
|
743
|
-
/** @deprecated Use {@link ApplicationCommandOptionEnum}. Removed in 0.3.0. */
|
|
744
|
-
export const ApplicationCommandOptionType = ApplicationCommandOptionEnum;
|
|
745
|
-
/** @deprecated Use {@link ApplicationCommandOptionEnum}. Removed in 0.3.0. */
|
|
746
|
-
export type ApplicationCommandOptionType = ApplicationCommandOptionEnum;
|