-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
ApplicationCommandOptionWithChoicesAndAutocompleteMixin.ts
80 lines (62 loc) · 2.37 KB
/
ApplicationCommandOptionWithChoicesAndAutocompleteMixin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { APIApplicationCommandOptionChoice, ApplicationCommandOptionType } from 'discord-api-types/v10';
import { z } from 'zod';
import { validateChoicesLength } from '../Assertions';
const stringPredicate = z.string().min(1).max(100);
const numberPredicate = z.number().gt(-Infinity).lt(Infinity);
const choicesPredicate = z
.object({ name: stringPredicate, value: z.union([stringPredicate, numberPredicate]) })
.array();
const booleanPredicate = z.boolean();
export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends string | number> {
public readonly choices?: APIApplicationCommandOptionChoice<T>[];
public readonly autocomplete?: boolean;
// Since this is present and this is a mixin, this is needed
public readonly type!: ApplicationCommandOptionType;
/**
* Adds multiple choices for this option
*
* @param choices The choices to add
*/
public addChoices(...choices: APIApplicationCommandOptionChoice<T>[]): this {
if (choices.length > 0 && this.autocomplete) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
choicesPredicate.parse(choices);
if (this.choices === undefined) {
Reflect.set(this, 'choices', []);
}
validateChoicesLength(choices.length, this.choices);
for (const { name, value } of choices) {
// Validate the value
if (this.type === ApplicationCommandOptionType.String) {
stringPredicate.parse(value);
} else {
numberPredicate.parse(value);
}
this.choices!.push({ name, value });
}
return this;
}
public setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {
if (choices.length > 0 && this.autocomplete) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
choicesPredicate.parse(choices);
Reflect.set(this, 'choices', []);
this.addChoices(...choices);
return this;
}
/**
* Marks the option as autocompletable
* @param autocomplete If this option should be autocompletable
*/
public setAutocomplete(autocomplete: boolean): this {
// Assert that you actually passed a boolean
booleanPredicate.parse(autocomplete);
if (autocomplete && Array.isArray(this.choices) && this.choices.length > 0) {
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
}
Reflect.set(this, 'autocomplete', autocomplete);
return this;
}
}