discordthing 0.1.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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -0
  3. package/build/bot.d.ts +37 -0
  4. package/build/bot.js +166 -0
  5. package/build/bot.js.map +1 -0
  6. package/build/commands/command.d.ts +111 -0
  7. package/build/commands/command.js +176 -0
  8. package/build/commands/command.js.map +1 -0
  9. package/build/commands/diff.d.ts +5 -0
  10. package/build/commands/diff.js +42 -0
  11. package/build/commands/diff.js.map +1 -0
  12. package/build/commands/index.d.ts +2 -0
  13. package/build/commands/index.js +2 -0
  14. package/build/commands/index.js.map +1 -0
  15. package/build/commands/registration.d.ts +10 -0
  16. package/build/commands/registration.js +40 -0
  17. package/build/commands/registration.js.map +1 -0
  18. package/build/context.d.ts +9 -0
  19. package/build/context.js +9 -0
  20. package/build/context.js.map +1 -0
  21. package/build/events/index.d.ts +2 -0
  22. package/build/events/index.js +2 -0
  23. package/build/events/index.js.map +1 -0
  24. package/build/events/listener.d.ts +24 -0
  25. package/build/events/listener.js +14 -0
  26. package/build/events/listener.js.map +1 -0
  27. package/build/index.d.ts +7 -0
  28. package/build/index.js +4 -0
  29. package/build/index.js.map +1 -0
  30. package/build/logger.d.ts +8 -0
  31. package/build/logger.js +2 -0
  32. package/build/logger.js.map +1 -0
  33. package/build/options/index.d.ts +3 -0
  34. package/build/options/index.js +2 -0
  35. package/build/options/index.js.map +1 -0
  36. package/build/options/option.d.ts +116 -0
  37. package/build/options/option.js +101 -0
  38. package/build/options/option.js.map +1 -0
  39. package/build/options/options.d.ts +78 -0
  40. package/build/options/options.js +169 -0
  41. package/build/options/options.js.map +1 -0
  42. package/build/permissions.d.ts +17 -0
  43. package/build/permissions.js +38 -0
  44. package/build/permissions.js.map +1 -0
  45. package/build/plugin.d.ts +20 -0
  46. package/build/plugin.js +22 -0
  47. package/build/plugin.js.map +1 -0
  48. package/build/utility-types.d.ts +15 -0
  49. package/build/utility-types.js +2 -0
  50. package/build/utility-types.js.map +1 -0
  51. package/build/utils.d.ts +2 -0
  52. package/build/utils.js +19 -0
  53. package/build/utils.js.map +1 -0
  54. package/package.json +56 -0
@@ -0,0 +1,78 @@
1
+ import { SlashCommandAttachmentOption, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption, type APIApplicationCommandOptionChoice, type ApplicationCommandNumericOptionMinMaxValueMixin, type ApplicationCommandOptionAllowedChannelTypes, type ApplicationCommandOptionBase, type ApplicationCommandOptionWithAutocompleteMixin, type ApplicationCommandOptionWithChoicesMixin, type Attachment, type GuildBasedChannel, type GuildMember, type LocalizationMap, type RestOrArray, type Role, type User } from "discord.js";
2
+ declare abstract class BaseOption<Type, IsOptional extends OptionalType = "required"> {
3
+ /**
4
+ * Only for Typescript.
5
+ */
6
+ readonly type: Type;
7
+ readonly isOptional: IsOptional;
8
+ constructor(isOptional: IsOptional);
9
+ }
10
+ export declare abstract class BuilderOption<Builder extends ApplicationCommandOptionBase, Type, IsOptional extends OptionalType = "required"> extends BaseOption<Type, IsOptional> {
11
+ protected builder: Builder;
12
+ constructor(builder: Builder, isOptional: IsOptional);
13
+ describe(description: string): this;
14
+ localize({ name, description }: {
15
+ name?: LocalizationMap;
16
+ description?: LocalizationMap;
17
+ }): this;
18
+ }
19
+ export declare class AttachmentOption<Type = Attachment, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandAttachmentOption, Type, IsOptional> {
20
+ constructor(builder: SlashCommandAttachmentOption, isOptional: IsOptional);
21
+ }
22
+ export declare class BooleanOption<Type = boolean, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandBooleanOption, Type, IsOptional> {
23
+ constructor(builder: SlashCommandBooleanOption, isOptional: IsOptional);
24
+ }
25
+ export declare class ChannelOption<Type = GuildBasedChannel, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandChannelOption, Type, IsOptional> {
26
+ constructor(builder: SlashCommandChannelOption, isOptional: IsOptional);
27
+ union<T extends ApplicationCommandOptionAllowedChannelTypes>(channelTypes: T[]): ChannelOption<Extract<GuildBasedChannel, {
28
+ type: T;
29
+ }>, IsOptional>;
30
+ }
31
+ declare abstract class AutocompleteOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin, Type, IsOptional extends OptionalType = "required"> extends BuilderOption<Builder, Type, IsOptional> {
32
+ autocomplete(autocomplete?: boolean): this;
33
+ }
34
+ export declare class Choice<Type extends number | string> {
35
+ readonly choice: APIApplicationCommandOptionChoice<Type>;
36
+ constructor(value: Type, name?: string);
37
+ localize({ name }: {
38
+ name?: LocalizationMap;
39
+ }): this;
40
+ }
41
+ type InferChoiceType<T extends ApplicationCommandOptionWithChoicesMixin<any>> = T extends ApplicationCommandOptionWithChoicesMixin<infer Type> ? Type : never;
42
+ declare abstract class ChoicesOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<any>, Type, IsOptional extends OptionalType = "required"> extends AutocompleteOption<Builder, Type, IsOptional> {
43
+ abstract union<UnionType extends InferChoiceType<Builder>>(...choices: RestOrArray<Choice<UnionType>>): Option<UnionType, IsOptional>;
44
+ }
45
+ declare abstract class NumbericOption<Builder extends ApplicationCommandOptionBase & ApplicationCommandNumericOptionMinMaxValueMixin & ApplicationCommandOptionWithAutocompleteMixin & ApplicationCommandOptionWithChoicesMixin<number>, Type = number, IsOptional extends OptionalType = "required"> extends ChoicesOption<Builder, Type, IsOptional> {
46
+ min(min: number): this;
47
+ max(max: number): this;
48
+ }
49
+ export declare class IntegerOption<Type = number, IsOptional extends OptionalType = "required"> extends NumbericOption<SlashCommandIntegerOption, Type, IsOptional> {
50
+ constructor(builder: SlashCommandIntegerOption, isOptional: IsOptional);
51
+ union<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>): IntegerOption<UnionType, IsOptional>;
52
+ }
53
+ export declare class NumberOption<Type = number, IsOptional extends OptionalType = "required"> extends NumbericOption<SlashCommandNumberOption, Type, IsOptional> {
54
+ constructor(builder: SlashCommandNumberOption, isOptional: IsOptional);
55
+ union<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>): NumberOption<UnionType, IsOptional>;
56
+ }
57
+ export declare class MentionableOption<Type = User | GuildMember | Role, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandMentionableOption, Type, IsOptional> {
58
+ constructor(builder: SlashCommandMentionableOption, isOptional: IsOptional);
59
+ }
60
+ export declare class RoleOption<Type = Role, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandRoleOption, Type, IsOptional> {
61
+ constructor(builder: SlashCommandRoleOption, isOptional: IsOptional);
62
+ }
63
+ export declare class StringOption<Type = string, IsOptional extends OptionalType = "required"> extends ChoicesOption<SlashCommandStringOption, Type, IsOptional> {
64
+ constructor(builder: SlashCommandStringOption, isOptional: IsOptional);
65
+ min(min: number): this;
66
+ max(max: number): this;
67
+ union<UnionType extends string>(...choices: RestOrArray<Choice<UnionType>>): StringOption<UnionType, IsOptional>;
68
+ }
69
+ export declare class UserOption<Type = User, IsOptional extends OptionalType = "required"> extends BuilderOption<SlashCommandUserOption, Type, IsOptional> {
70
+ constructor(builder: SlashCommandUserOption, isOptional: IsOptional);
71
+ }
72
+ /**
73
+ * A type representing whether an option is optional or not.
74
+ */
75
+ export type OptionalType = "required" | "optional";
76
+ export type AsOptional<T extends Option<any, OptionalType>> = T extends AttachmentOption<infer Type, OptionalType> ? AttachmentOption<Type, "optional"> : T extends BooleanOption<infer Type, OptionalType> ? BooleanOption<Type, "optional"> : T extends ChannelOption<infer Type, OptionalType> ? ChannelOption<Type, "optional"> : T extends IntegerOption<infer Type, OptionalType> ? IntegerOption<Type, "optional"> : T extends NumberOption<infer Type, OptionalType> ? NumberOption<Type, "optional"> : T extends MentionableOption<infer Type, OptionalType> ? MentionableOption<Type, "optional"> : T extends RoleOption<infer Type, OptionalType> ? RoleOption<Type, "optional"> : T extends StringOption<infer Type, OptionalType> ? StringOption<Type, "optional"> : T extends UserOption<infer Type, OptionalType> ? UserOption<Type, "optional"> : never;
77
+ export type Option<Type, IsOptional extends OptionalType = "required"> = AttachmentOption<Type, IsOptional> | BooleanOption<Type, IsOptional> | ChannelOption<Type, IsOptional> | IntegerOption<Type, IsOptional> | NumberOption<Type, IsOptional> | MentionableOption<Type, IsOptional> | RoleOption<Type, IsOptional> | StringOption<Type, IsOptional> | UserOption<Type, IsOptional>;
78
+ export {};
@@ -0,0 +1,169 @@
1
+ import { SlashCommandAttachmentOption, SlashCommandBooleanOption, SlashCommandChannelOption, SlashCommandIntegerOption, SlashCommandMentionableOption, SlashCommandNumberOption, SlashCommandRoleOption, SlashCommandStringOption, SlashCommandUserOption } from "discord.js";
2
+ class BaseOption {
3
+ /**
4
+ * Only for Typescript.
5
+ */
6
+ type;
7
+ isOptional;
8
+ constructor(isOptional) {
9
+ this.isOptional = isOptional;
10
+ }
11
+ }
12
+ export class BuilderOption extends BaseOption {
13
+ builder;
14
+ constructor(builder, isOptional) {
15
+ super(isOptional);
16
+ this.builder = builder.setRequired(isOptional === "optional" ? false : true);
17
+ }
18
+ describe(description) {
19
+ this.builder = this.builder.setDescription(description);
20
+ return this;
21
+ }
22
+ localize({ name, description }) {
23
+ this.builder = this.builder
24
+ .setNameLocalizations(name ?? null)
25
+ .setDescriptionLocalizations(description ?? null);
26
+ return this;
27
+ }
28
+ /** @internal */
29
+ getBuilder() {
30
+ return this.builder;
31
+ }
32
+ }
33
+ export class AttachmentOption extends BuilderOption {
34
+ constructor(builder, isOptional) {
35
+ super(builder, isOptional);
36
+ }
37
+ /** @internal */
38
+ asOptional() {
39
+ return new AttachmentOption(this.builder, "optional");
40
+ }
41
+ }
42
+ export class BooleanOption extends BuilderOption {
43
+ constructor(builder, isOptional) {
44
+ super(builder, isOptional);
45
+ }
46
+ /** @internal */
47
+ asOptional() {
48
+ return new BooleanOption(this.builder, "optional");
49
+ }
50
+ }
51
+ export class ChannelOption extends BuilderOption {
52
+ constructor(builder, isOptional) {
53
+ super(builder, isOptional);
54
+ }
55
+ union(channelTypes) {
56
+ this.builder = this.builder.addChannelTypes(channelTypes);
57
+ return this;
58
+ }
59
+ /** @internal */
60
+ asOptional() {
61
+ return new ChannelOption(this.builder, "optional");
62
+ }
63
+ }
64
+ class AutocompleteOption extends BuilderOption {
65
+ autocomplete(autocomplete = true) {
66
+ this.builder = this.builder.setAutocomplete(autocomplete);
67
+ return this;
68
+ }
69
+ }
70
+ export class Choice {
71
+ choice;
72
+ constructor(value, name) {
73
+ this.choice = {
74
+ name: name ?? value.toString(),
75
+ value
76
+ };
77
+ }
78
+ localize({ name }) {
79
+ this.choice.name_localizations = name ?? null;
80
+ return this;
81
+ }
82
+ }
83
+ class ChoicesOption extends AutocompleteOption {
84
+ }
85
+ class NumbericOption extends ChoicesOption {
86
+ min(min) {
87
+ this.builder = this.builder.setMinValue(min);
88
+ return this;
89
+ }
90
+ max(max) {
91
+ this.builder = this.builder.setMaxValue(max);
92
+ return this;
93
+ }
94
+ }
95
+ export class IntegerOption extends NumbericOption {
96
+ constructor(builder, isOptional) {
97
+ super(builder, isOptional);
98
+ }
99
+ union(...choices) {
100
+ this.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));
101
+ return this;
102
+ }
103
+ /** @internal */
104
+ asOptional() {
105
+ return new IntegerOption(this.builder, "optional");
106
+ }
107
+ }
108
+ export class NumberOption extends NumbericOption {
109
+ constructor(builder, isOptional) {
110
+ super(builder, isOptional);
111
+ }
112
+ union(...choices) {
113
+ this.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));
114
+ return this;
115
+ }
116
+ /** @internal */
117
+ asOptional() {
118
+ return new NumberOption(this.builder, "optional");
119
+ }
120
+ }
121
+ export class MentionableOption extends BuilderOption {
122
+ constructor(builder, isOptional) {
123
+ super(builder, isOptional);
124
+ }
125
+ /** @internal */
126
+ asOptional() {
127
+ return new MentionableOption(this.builder, "optional");
128
+ }
129
+ }
130
+ export class RoleOption extends BuilderOption {
131
+ constructor(builder, isOptional) {
132
+ super(builder, isOptional);
133
+ }
134
+ /** @internal */
135
+ asOptional() {
136
+ return new RoleOption(this.builder, "optional");
137
+ }
138
+ }
139
+ export class StringOption extends ChoicesOption {
140
+ constructor(builder, isOptional) {
141
+ super(builder, isOptional);
142
+ }
143
+ min(min) {
144
+ this.builder = this.builder.setMinLength(min);
145
+ return this;
146
+ }
147
+ max(max) {
148
+ this.builder = this.builder.setMaxLength(max);
149
+ return this;
150
+ }
151
+ union(...choices) {
152
+ this.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));
153
+ return this;
154
+ }
155
+ /** @internal */
156
+ asOptional() {
157
+ return new StringOption(this.builder, "optional");
158
+ }
159
+ }
160
+ export class UserOption extends BuilderOption {
161
+ constructor(builder, isOptional) {
162
+ super(builder, isOptional);
163
+ }
164
+ /** @internal */
165
+ asOptional() {
166
+ return new UserOption(this.builder, "optional");
167
+ }
168
+ }
169
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options/options.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tSlashCommandAttachmentOption,\n\tSlashCommandBooleanOption,\n\tSlashCommandChannelOption,\n\tSlashCommandIntegerOption,\n\tSlashCommandMentionableOption,\n\tSlashCommandNumberOption,\n\tSlashCommandRoleOption,\n\tSlashCommandStringOption,\n\tSlashCommandUserOption,\n\ttype APIApplicationCommandOptionChoice,\n\ttype ApplicationCommandNumericOptionMinMaxValueMixin,\n\ttype ApplicationCommandOptionAllowedChannelTypes,\n\ttype ApplicationCommandOptionBase,\n\ttype ApplicationCommandOptionWithAutocompleteMixin,\n\ttype ApplicationCommandOptionWithChoicesMixin,\n\ttype Attachment,\n\ttype GuildBasedChannel,\n\ttype GuildMember,\n\ttype LocalizationMap,\n\ttype RestOrArray,\n\ttype Role,\n\ttype User\n} from \"discord.js\";\n\nabstract class BaseOption<Type, IsOptional extends OptionalType = \"required\"> {\n\t/**\n\t * Only for Typescript.\n\t */\n\treadonly type!: Type;\n\n\treadonly isOptional: IsOptional;\n\n\tconstructor(isOptional: IsOptional) {\n\t\tthis.isOptional = isOptional;\n\t}\n\n\t/** @internal */\n\tabstract asOptional(): Option<Type, \"optional\">;\n}\n\nexport abstract class BuilderOption<\n\tBuilder extends ApplicationCommandOptionBase,\n\tType,\n\tIsOptional extends OptionalType = \"required\"\n> extends BaseOption<Type, IsOptional> {\n\tprotected builder: Builder;\n\n\tconstructor(builder: Builder, isOptional: IsOptional) {\n\t\tsuper(isOptional);\n\t\tthis.builder = builder.setRequired(isOptional === \"optional\" ? false : true);\n\t}\n\n\tdescribe(description: string) {\n\t\tthis.builder = this.builder.setDescription(description);\n\t\treturn this;\n\t}\n\n\tlocalize({ name, description }: { name?: LocalizationMap; description?: LocalizationMap }) {\n\t\tthis.builder = this.builder\n\t\t\t.setNameLocalizations(name ?? null)\n\t\t\t.setDescriptionLocalizations(description ?? null);\n\t\treturn this;\n\t}\n\n\t/** @internal */\n\tgetBuilder() {\n\t\treturn this.builder;\n\t}\n}\n\nexport class AttachmentOption<\n\tType = Attachment,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandAttachmentOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandAttachmentOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new AttachmentOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class BooleanOption<\n\tType = boolean,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandBooleanOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandBooleanOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new BooleanOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class ChannelOption<\n\tType = GuildBasedChannel,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandChannelOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandChannelOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\tunion<T extends ApplicationCommandOptionAllowedChannelTypes>(channelTypes: T[]) {\n\t\tthis.builder = this.builder.addChannelTypes(channelTypes);\n\t\treturn this as ChannelOption<\n\t\t\tExtract<\n\t\t\t\tGuildBasedChannel,\n\t\t\t\t{\n\t\t\t\t\ttype: T;\n\t\t\t\t}\n\t\t\t>,\n\t\t\tIsOptional\n\t\t>;\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new ChannelOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nabstract class AutocompleteOption<\n\tBuilder extends ApplicationCommandOptionBase & ApplicationCommandOptionWithAutocompleteMixin,\n\tType,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<Builder, Type, IsOptional> {\n\tautocomplete(autocomplete = true) {\n\t\tthis.builder = this.builder.setAutocomplete(autocomplete);\n\t\treturn this;\n\t}\n}\n\nexport class Choice<Type extends number | string> {\n\treadonly choice: APIApplicationCommandOptionChoice<Type>;\n\n\tconstructor(value: Type, name?: string) {\n\t\tthis.choice = {\n\t\t\tname: name ?? value.toString(),\n\t\t\tvalue\n\t\t};\n\t}\n\n\tlocalize({ name }: { name?: LocalizationMap }) {\n\t\tthis.choice.name_localizations = name ?? null;\n\t\treturn this;\n\t}\n}\n\ntype InferChoiceType<T extends ApplicationCommandOptionWithChoicesMixin<any>> =\n\tT extends ApplicationCommandOptionWithChoicesMixin<infer Type> ? Type : never;\n\nabstract class ChoicesOption<\n\tBuilder extends ApplicationCommandOptionBase &\n\t\tApplicationCommandOptionWithAutocompleteMixin &\n\t\tApplicationCommandOptionWithChoicesMixin<any>,\n\tType,\n\tIsOptional extends OptionalType = \"required\"\n> extends AutocompleteOption<Builder, Type, IsOptional> {\n\tabstract union<UnionType extends InferChoiceType<Builder>>(\n\t\t...choices: RestOrArray<Choice<UnionType>>\n\t): Option<UnionType, IsOptional>;\n}\n\nabstract class NumbericOption<\n\tBuilder extends ApplicationCommandOptionBase &\n\t\tApplicationCommandNumericOptionMinMaxValueMixin &\n\t\tApplicationCommandOptionWithAutocompleteMixin &\n\t\tApplicationCommandOptionWithChoicesMixin<number>,\n\tType = number,\n\tIsOptional extends OptionalType = \"required\"\n> extends ChoicesOption<Builder, Type, IsOptional> {\n\tmin(min: number) {\n\t\tthis.builder = this.builder.setMinValue(min);\n\t\treturn this;\n\t}\n\n\tmax(max: number) {\n\t\tthis.builder = this.builder.setMaxValue(max);\n\t\treturn this;\n\t}\n}\n\nexport class IntegerOption<\n\tType = number,\n\tIsOptional extends OptionalType = \"required\"\n> extends NumbericOption<SlashCommandIntegerOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandIntegerOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\tunion<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>) {\n\t\tthis.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));\n\t\treturn this as unknown as IntegerOption<UnionType, IsOptional>;\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new IntegerOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class NumberOption<\n\tType = number,\n\tIsOptional extends OptionalType = \"required\"\n> extends NumbericOption<SlashCommandNumberOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandNumberOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\tunion<UnionType extends number>(...choices: RestOrArray<Choice<UnionType>>) {\n\t\tthis.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));\n\t\treturn this as unknown as NumberOption<UnionType, IsOptional>;\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new NumberOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class MentionableOption<\n\tType = User | GuildMember | Role,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandMentionableOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandMentionableOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new MentionableOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class RoleOption<\n\tType = Role,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandRoleOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandRoleOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new RoleOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class StringOption<\n\tType = string,\n\tIsOptional extends OptionalType = \"required\"\n> extends ChoicesOption<SlashCommandStringOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandStringOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\tmin(min: number) {\n\t\tthis.builder = this.builder.setMinLength(min);\n\t\treturn this;\n\t}\n\n\tmax(max: number) {\n\t\tthis.builder = this.builder.setMaxLength(max);\n\t\treturn this;\n\t}\n\n\tunion<UnionType extends string>(...choices: RestOrArray<Choice<UnionType>>) {\n\t\tthis.builder = this.builder.addChoices(choices.flat().map((choice) => choice.choice));\n\t\treturn this as unknown as StringOption<UnionType, IsOptional>;\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new StringOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\nexport class UserOption<\n\tType = User,\n\tIsOptional extends OptionalType = \"required\"\n> extends BuilderOption<SlashCommandUserOption, Type, IsOptional> {\n\tconstructor(builder: SlashCommandUserOption, isOptional: IsOptional) {\n\t\tsuper(builder, isOptional);\n\t}\n\n\t/** @internal */\n\tasOptional() {\n\t\treturn new UserOption<Type, \"optional\">(this.builder, \"optional\");\n\t}\n}\n\n/**\n * A type representing whether an option is optional or not.\n */\nexport type OptionalType = \"required\" | \"optional\";\n\n// prettier-ignore\nexport type AsOptional<T extends Option<any, OptionalType>> =\n\tT extends AttachmentOption<infer Type, OptionalType>\n\t\t? AttachmentOption<Type, \"optional\">\n\t: T extends BooleanOption<infer Type, OptionalType>\n\t\t? BooleanOption<Type, \"optional\">\n\t: T extends ChannelOption<infer Type, OptionalType>\n\t\t? ChannelOption<Type, \"optional\">\n\t: T extends IntegerOption<infer Type, OptionalType>\n\t\t? IntegerOption<Type, \"optional\">\n\t: T extends NumberOption<infer Type, OptionalType>\n\t\t? NumberOption<Type, \"optional\">\n\t: T extends MentionableOption<infer Type, OptionalType>\n\t\t? MentionableOption<Type, \"optional\">\n\t: T extends RoleOption<infer Type, OptionalType>\n\t\t? RoleOption<Type, \"optional\">\n\t: T extends StringOption<infer Type, OptionalType>\n\t\t? StringOption<Type, \"optional\">\n\t: T extends UserOption<infer Type, OptionalType>\n\t\t? UserOption<Type, \"optional\">\n\t: never;\n\nexport type Option<Type, IsOptional extends OptionalType = \"required\"> =\n\t| AttachmentOption<Type, IsOptional>\n\t| BooleanOption<Type, IsOptional>\n\t| ChannelOption<Type, IsOptional>\n\t| IntegerOption<Type, IsOptional>\n\t| NumberOption<Type, IsOptional>\n\t| MentionableOption<Type, IsOptional>\n\t| RoleOption<Type, IsOptional>\n\t| StringOption<Type, IsOptional>\n\t| UserOption<Type, IsOptional>;\n"]}
@@ -0,0 +1,17 @@
1
+ import { PermissionFlagsBits, type Guild, type GuildChannelResolvable, type GuildMember, type PermissionResolvable } from "discord.js";
2
+ import type { Bot } from "./bot.js";
3
+ export type PermissionName = keyof typeof PermissionFlagsBits;
4
+ export type SinglePermissionResolvable = Exclude<PermissionResolvable, any[]>;
5
+ export declare class PermissionsResolver {
6
+ private readonly bot;
7
+ constructor(bot: Bot);
8
+ checkSelf(permissions: SinglePermissionResolvable[], guild: Guild, channel?: GuildChannelResolvable): Promise<import("@l3dev/result").Err<"GET_ME", object & {
9
+ error: Error;
10
+ }> | import("@l3dev/result").Err<"MISSING_PERMISSIONS", {
11
+ missingPermissions: ("CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTTSMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "ViewGuildInsights" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVAD" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageGuildExpressions" | "UseApplicationCommands" | "RequestToSpeak" | "ManageEvents" | "ManageThreads" | "CreatePublicThreads" | "CreatePrivateThreads" | "UseExternalStickers" | "SendMessagesInThreads" | "UseEmbeddedActivities" | "ModerateMembers" | "ViewCreatorMonetizationAnalytics" | "UseSoundboard" | "CreateGuildExpressions" | "CreateEvents" | "UseExternalSounds" | "SendVoiceMessages" | "SendPolls" | "UseExternalApps" | "PinMessages" | "BypassSlowmode")[];
12
+ }> | import("@l3dev/result").None>;
13
+ check(member: GuildMember, permissions: SinglePermissionResolvable[], channel?: GuildChannelResolvable): import("@l3dev/result").Err<"MISSING_PERMISSIONS", {
14
+ missingPermissions: ("CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTTSMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "ViewGuildInsights" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVAD" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageGuildExpressions" | "UseApplicationCommands" | "RequestToSpeak" | "ManageEvents" | "ManageThreads" | "CreatePublicThreads" | "CreatePrivateThreads" | "UseExternalStickers" | "SendMessagesInThreads" | "UseEmbeddedActivities" | "ModerateMembers" | "ViewCreatorMonetizationAnalytics" | "UseSoundboard" | "CreateGuildExpressions" | "CreateEvents" | "UseExternalSounds" | "SendVoiceMessages" | "SendPolls" | "UseExternalApps" | "PinMessages" | "BypassSlowmode")[];
15
+ }> | import("@l3dev/result").None;
16
+ resolveName(permission: SinglePermissionResolvable): PermissionName;
17
+ }
@@ -0,0 +1,38 @@
1
+ import { err, NONE } from "@l3dev/result";
2
+ import { BitField, PermissionFlagsBits } from "discord.js";
3
+ export class PermissionsResolver {
4
+ bot;
5
+ constructor(bot) {
6
+ this.bot = bot;
7
+ }
8
+ async checkSelf(permissions, guild, channel) {
9
+ const member = await this.bot.getMe(guild);
10
+ if (!member.ok)
11
+ return member;
12
+ return this.check(member.value, permissions, channel);
13
+ }
14
+ check(member, permissions, channel) {
15
+ const memberPermissions = channel ? member.permissionsIn(channel) : member.permissions;
16
+ const missingPermissions = [];
17
+ for (const permission of permissions) {
18
+ if (!memberPermissions.has(permission, true)) {
19
+ missingPermissions.push(this.resolveName(permission));
20
+ }
21
+ }
22
+ if (missingPermissions.length) {
23
+ return err("MISSING_PERMISSIONS", {
24
+ missingPermissions
25
+ });
26
+ }
27
+ return NONE;
28
+ }
29
+ resolveName(permission) {
30
+ const bit = BitField.resolve(permission);
31
+ const entry = Object.entries(PermissionFlagsBits).find(([_, value]) => value === bit);
32
+ if (!entry) {
33
+ throw new Error(`Unknown permission: ${bit}`);
34
+ }
35
+ return entry[0];
36
+ }
37
+ }
38
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EACN,QAAQ,EACR,mBAAmB,EAKnB,MAAM,YAAY,CAAC;AAQpB,MAAM,OAAO,mBAAmB;IACF;IAA7B,YAA6B,GAAQ;QAAR,QAAG,GAAH,GAAG,CAAK;IAAG,CAAC;IAEzC,KAAK,CAAC,SAAS,CACd,WAAyC,EACzC,KAAY,EACZ,OAAgC;QAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC;QAE9B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CACJ,MAAmB,EACnB,WAAyC,EACzC,OAAgC;QAEhC,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QAEvF,MAAM,kBAAkB,GAAqB,EAAE,CAAC;QAChD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACtC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC9C,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;YACvD,CAAC;QACF,CAAC;QAED,IAAI,kBAAkB,CAAC,MAAM,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,qBAAqB,EAAE;gBACjC,kBAAkB;aAClB,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,WAAW,CAAC,UAAsC;QACjD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAEzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;QACtF,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,KAAK,CAAC,CAAC,CAAmB,CAAC;IACnC,CAAC;CACD","sourcesContent":["import { err, NONE } from \"@l3dev/result\";\nimport {\n\tBitField,\n\tPermissionFlagsBits,\n\ttype Guild,\n\ttype GuildChannelResolvable,\n\ttype GuildMember,\n\ttype PermissionResolvable\n} from \"discord.js\";\n\nimport type { Bot } from \"./bot.js\";\n\nexport type PermissionName = keyof typeof PermissionFlagsBits;\n\nexport type SinglePermissionResolvable = Exclude<PermissionResolvable, any[]>;\n\nexport class PermissionsResolver {\n\tconstructor(private readonly bot: Bot) {}\n\n\tasync checkSelf(\n\t\tpermissions: SinglePermissionResolvable[],\n\t\tguild: Guild,\n\t\tchannel?: GuildChannelResolvable\n\t) {\n\t\tconst member = await this.bot.getMe(guild);\n\t\tif (!member.ok) return member;\n\n\t\treturn this.check(member.value, permissions, channel);\n\t}\n\n\tcheck(\n\t\tmember: GuildMember,\n\t\tpermissions: SinglePermissionResolvable[],\n\t\tchannel?: GuildChannelResolvable\n\t) {\n\t\tconst memberPermissions = channel ? member.permissionsIn(channel) : member.permissions;\n\n\t\tconst missingPermissions: PermissionName[] = [];\n\t\tfor (const permission of permissions) {\n\t\t\tif (!memberPermissions.has(permission, true)) {\n\t\t\t\tmissingPermissions.push(this.resolveName(permission));\n\t\t\t}\n\t\t}\n\n\t\tif (missingPermissions.length) {\n\t\t\treturn err(\"MISSING_PERMISSIONS\", {\n\t\t\t\tmissingPermissions\n\t\t\t});\n\t\t}\n\n\t\treturn NONE;\n\t}\n\n\tresolveName(permission: SinglePermissionResolvable): PermissionName {\n\t\tconst bit = BitField.resolve(permission);\n\n\t\tconst entry = Object.entries(PermissionFlagsBits).find(([_, value]) => value === bit);\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Unknown permission: ${bit}`);\n\t\t}\n\n\t\treturn entry[0] as PermissionName;\n\t}\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import type { SlashCommandBuilder } from "discord.js";
2
+ import type { Bot, BotOptions } from "./bot.js";
3
+ import type { Command } from "./commands/command.js";
4
+ import type { Listener } from "./events/listener.js";
5
+ export type PluginOptions = {
6
+ name: string;
7
+ commands?: Command<string, SlashCommandBuilder>[];
8
+ listeners?: Listener<any>[];
9
+ resolved?: (plugin: ResolvedPlugin, bot: Bot) => void;
10
+ };
11
+ export declare class ResolvedPlugin {
12
+ private readonly options;
13
+ readonly name: string;
14
+ readonly commands: Command<string, SlashCommandBuilder>[];
15
+ readonly listeners: Listener<any>[];
16
+ constructor(options: PluginOptions);
17
+ resolved(bot: Bot): void;
18
+ }
19
+ export type Plugin = (botOptions: BotOptions) => ResolvedPlugin;
20
+ export declare function plugin(options: PluginOptions | ((botOptions: BotOptions) => PluginOptions)): Plugin;
@@ -0,0 +1,22 @@
1
+ export class ResolvedPlugin {
2
+ options;
3
+ name;
4
+ commands;
5
+ listeners;
6
+ constructor(options) {
7
+ this.options = options;
8
+ this.name = options.name;
9
+ this.commands = options.commands ?? [];
10
+ this.listeners = options.listeners ?? [];
11
+ }
12
+ resolved(bot) {
13
+ this.options.resolved?.(this, bot);
14
+ }
15
+ }
16
+ export function plugin(options) {
17
+ return (botOptions) => {
18
+ const resolvedOptions = typeof options === "function" ? options(botOptions) : options;
19
+ return new ResolvedPlugin(resolvedOptions);
20
+ };
21
+ }
22
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,cAAc;IAKG;IAJpB,IAAI,CAAS;IACb,QAAQ,CAAyC;IACjD,SAAS,CAAkB;IAEpC,YAA6B,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;QAClD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,QAAQ,CAAC,GAAQ;QAChB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;CACD;AAID,MAAM,UAAU,MAAM,CACrB,OAAoE;IAEpE,OAAO,CAAC,UAAU,EAAE,EAAE;QACrB,MAAM,eAAe,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACtF,OAAO,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC,CAAC;AACH,CAAC","sourcesContent":["import type { SlashCommandBuilder } from \"discord.js\";\n\nimport type { Bot, BotOptions } from \"./bot.js\";\nimport type { Command } from \"./commands/command.js\";\nimport type { Listener } from \"./events/listener.js\";\n\nexport type PluginOptions = {\n\tname: string;\n\tcommands?: Command<string, SlashCommandBuilder>[];\n\tlisteners?: Listener<any>[];\n\tresolved?: (plugin: ResolvedPlugin, bot: Bot) => void;\n};\n\nexport class ResolvedPlugin {\n\treadonly name: string;\n\treadonly commands: Command<string, SlashCommandBuilder>[];\n\treadonly listeners: Listener<any>[];\n\n\tconstructor(private readonly options: PluginOptions) {\n\t\tthis.name = options.name;\n\t\tthis.commands = options.commands ?? [];\n\t\tthis.listeners = options.listeners ?? [];\n\t}\n\n\tresolved(bot: Bot) {\n\t\tthis.options.resolved?.(this, bot);\n\t}\n}\n\nexport type Plugin = (botOptions: BotOptions) => ResolvedPlugin;\n\nexport function plugin(\n\toptions: PluginOptions | ((botOptions: BotOptions) => PluginOptions)\n): Plugin {\n\treturn (botOptions) => {\n\t\tconst resolvedOptions = typeof options === \"function\" ? options(botOptions) : options;\n\t\treturn new ResolvedPlugin(resolvedOptions);\n\t};\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export type MaybePromise<T> = T | Promise<T>;
2
+ /**
3
+ * Hack! This type causes TypeScript to simplify how it renders object types.
4
+ *
5
+ * It is functionally the identity for object types, but in practice it can
6
+ * simplify expressions like `A & B`.
7
+ */
8
+ export type Expand<ObjectType extends Record<any, any>> = ObjectType extends Record<any, any> ? {
9
+ [Key in keyof ObjectType]: ObjectType[Key];
10
+ } : never;
11
+ /**
12
+ * Convert a union type like `A | B | C` into an intersection type like
13
+ * `A & B & C`.
14
+ */
15
+ export type UnionToIntersection<UnionType> = (UnionType extends any ? (k: UnionType) => void : never) extends (k: infer I) => void ? I : never;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utility-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utility-types.js","sourceRoot":"","sources":["../src/utility-types.ts"],"names":[],"mappings":"","sourcesContent":["export type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Hack! This type causes TypeScript to simplify how it renders object types.\n *\n * It is functionally the identity for object types, but in practice it can\n * simplify expressions like `A & B`.\n */\nexport type Expand<ObjectType extends Record<any, any>> =\n\tObjectType extends Record<any, any>\n\t\t? {\n\t\t\t\t[Key in keyof ObjectType]: ObjectType[Key];\n\t\t\t}\n\t\t: never;\n\n/**\n * Convert a union type like `A | B | C` into an intersection type like\n * `A & B & C`.\n */\nexport type UnionToIntersection<UnionType> = (\n\tUnionType extends any ? (k: UnionType) => void : never\n) extends (k: infer I) => void\n\t? I\n\t: never;\n"]}
@@ -0,0 +1,2 @@
1
+ import { type BitFieldResolvable, type MessageFlags, type MessageFlagsString } from "discord.js";
2
+ export declare function mergeMessageFlags<TFlag extends MessageFlagsString, TType extends MessageFlags>(...flags: (BitFieldResolvable<TFlag, TType> | null | undefined)[]): (`${bigint}` | TFlag | TType)[];
package/build/utils.js ADDED
@@ -0,0 +1,19 @@
1
+ import { BitField } from "discord.js";
2
+ export function mergeMessageFlags(...flags) {
3
+ const mergedFlags = [];
4
+ for (const flag of flags) {
5
+ if (!flag)
6
+ continue;
7
+ if (Array.isArray(flag)) {
8
+ mergedFlags.push(...flag);
9
+ }
10
+ else if (flag instanceof BitField) {
11
+ mergedFlags.push(flag.bitfield);
12
+ }
13
+ else {
14
+ mergedFlags.push(flag);
15
+ }
16
+ }
17
+ return mergedFlags;
18
+ }
19
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,QAAQ,EAIR,MAAM,YAAY,CAAC;AAEpB,MAAM,UAAU,iBAAiB,CAChC,GAAG,KAA8D;IAEjE,MAAM,WAAW,GAAoC,EAAE,CAAC;IAExD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,IAAI,YAAY,QAAQ,EAAE,CAAC;YACrC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACP,WAAW,CAAC,IAAI,CAAC,IAAmC,CAAC,CAAC;QACvD,CAAC;IACF,CAAC;IAED,OAAO,WAAW,CAAC;AACpB,CAAC","sourcesContent":["import {\n\tBitField,\n\ttype BitFieldResolvable,\n\ttype MessageFlags,\n\ttype MessageFlagsString\n} from \"discord.js\";\n\nexport function mergeMessageFlags<TFlag extends MessageFlagsString, TType extends MessageFlags>(\n\t...flags: (BitFieldResolvable<TFlag, TType> | null | undefined)[]\n) {\n\tconst mergedFlags: (TFlag | TType | `${bigint}`)[] = [];\n\n\tfor (const flag of flags) {\n\t\tif (!flag) continue;\n\n\t\tif (Array.isArray(flag)) {\n\t\t\tmergedFlags.push(...flag);\n\t\t} else if (flag instanceof BitField) {\n\t\t\tmergedFlags.push(flag.bitfield);\n\t\t} else {\n\t\t\tmergedFlags.push(flag as TFlag | TType | `${bigint}`);\n\t\t}\n\t}\n\n\treturn mergedFlags;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "discordthing",
3
+ "version": "0.1.0",
4
+ "description": "A lightweight framework for building discord bots built on-top of discord.js",
5
+ "type": "module",
6
+ "main": "./build/index.js",
7
+ "types": "./build/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./build/index.d.ts",
11
+ "import": "./build/index.js"
12
+ },
13
+ "./options": {
14
+ "types": "./build/options/index.d.ts",
15
+ "import": "./build/options/index.js"
16
+ },
17
+ "./commands": {
18
+ "types": "./build/commands/index.d.ts",
19
+ "import": "./build/commands/index.js"
20
+ },
21
+ "./events": {
22
+ "types": "./build/events/index.d.ts",
23
+ "import": "./build/events/index.js"
24
+ },
25
+ "./utils": {
26
+ "types": "./build/utils.d.ts",
27
+ "import": "./build/utils.js"
28
+ }
29
+ },
30
+ "files": [
31
+ "build",
32
+ "!build/**/*.test.*"
33
+ ],
34
+ "author": "l3dotdev",
35
+ "license": "MIT",
36
+ "homepage": "https://github.com/l3dotdev/discordthing",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/l3dotdev/discordthing.git"
40
+ },
41
+ "peerDependencies": {
42
+ "discord.js": "^14.25.0"
43
+ },
44
+ "dependencies": {
45
+ "@l3dev/result": "^0.6.1",
46
+ "tslog": "^4.10.2"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "package": "pnpm build",
51
+ "eslint": "eslint .",
52
+ "lint": "eslint . && prettier --check .",
53
+ "lint-fix": "eslint . --fix && prettier --write .",
54
+ "format": "prettier --write ."
55
+ }
56
+ }