feat: Make message components great (#163)

* fix: mentionables defaults

* feat: make message api components great

* fix: add url to button link
This commit is contained in:
Marcos Susaña 2024-03-27 17:53:28 -04:00 committed by GitHub
parent 84f1ccf0ce
commit 89c525d052
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 184 additions and 115 deletions

View File

@ -5,9 +5,7 @@
"main": "./lib/index.js", "main": "./lib/index.js",
"module": "./lib/index.js", "module": "./lib/index.js",
"types": "./lib/index.d.ts", "types": "./lib/index.d.ts",
"files": [ "files": ["lib/**"],
"lib/**"
],
"scripts": { "scripts": {
"build": "tsc --outDir ./lib", "build": "tsc --outDir ./lib",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
@ -15,7 +13,7 @@
"lint": "biome lint --apply ./src", "lint": "biome lint --apply ./src",
"format": "biome format --write ./src", "format": "biome format --write ./src",
"check-h": "biome check --apply ./src", "check-h": "biome check --apply ./src",
"check": "biome check --apply --changed --no-errors-on-unmatched ./src" "check": "biome check --apply --no-errors-on-unmatched ./src"
}, },
"author": "MARCROCK22", "author": "MARCROCK22",
"license": "Apache-2.0", "license": "Apache-2.0",
@ -27,10 +25,7 @@
"ws": "^8.16.0" "ws": "^8.16.0"
}, },
"lint-staged": { "lint-staged": {
"*.ts": [ "*.ts": ["biome check --apply", "biome format --write"]
"biome check --apply",
"biome format --write"
]
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.6.0", "@biomejs/biome": "1.6.0",
@ -55,13 +50,7 @@
"bugs": { "bugs": {
"url": "https://github.com/tiramisulabs/seyfert" "url": "https://github.com/tiramisulabs/seyfert"
}, },
"keywords": [ "keywords": ["api", "discord", "bots", "typescript", "botdev"],
"api",
"discord",
"bots",
"typescript",
"botdev"
],
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },

View File

@ -1,18 +1,21 @@
import type { APIMessageActionRowComponent, ComponentType } from '../common'; import type { APIMessageActionRowComponent, ComponentType } from '../common';
import { BaseComponent } from '../structures/extra/BaseComponent'; import { BaseComponent } from './BaseComponent';
import type { ActionRowMessageComponents } from './index'; import type { ActionRowMessageComponents } from './index';
import { componentFactory } from './index'; import { componentFactory } from './index';
export class MessageActionRowComponent< export class MessageActionRowComponent<
T extends ActionRowMessageComponents, T extends ActionRowMessageComponents,
> extends BaseComponent<ComponentType.ActionRow> { > extends BaseComponent<ComponentType.ActionRow> {
private ComponentsFactory: T[];
constructor(data: { constructor(data: {
type: ComponentType.ActionRow; type: ComponentType.ActionRow;
components: APIMessageActionRowComponent[]; components: APIMessageActionRowComponent[];
}) { }) {
super(data); super(data);
this.components = data.components.map(componentFactory) as T[]; this.ComponentsFactory = data.components.map(componentFactory) as T[];
} }
components: T[]; get components() {
return this.ComponentsFactory;
}
} }

View File

@ -0,0 +1,39 @@
import { fromComponent } from '../builders';
import type {
APIActionRowComponent,
APIActionRowComponentTypes,
APIButtonComponent,
APIChannelSelectComponent,
APIMentionableSelectComponent,
APIRoleSelectComponent,
APIStringSelectComponent,
APITextInputComponent,
APIUserSelectComponent,
ComponentType,
} from '../common';
export class BaseComponent<T extends ComponentType> {
constructor(public data: APIComponentsMap[T]) {}
get type() {
return this.data.type;
}
toJSON() {
return this.data;
}
toBuilder() {
return fromComponent(this.data);
}
}
export interface APIComponentsMap {
[ComponentType.ActionRow]: APIActionRowComponent<APIActionRowComponentTypes>;
[ComponentType.Button]: APIButtonComponent;
[ComponentType.ChannelSelect]: APIChannelSelectComponent;
[ComponentType.MentionableSelect]: APIMentionableSelectComponent;
[ComponentType.RoleSelect]: APIRoleSelectComponent;
[ComponentType.StringSelect]: APIStringSelectComponent;
[ComponentType.UserSelect]: APIUserSelectComponent;
[ComponentType.TextInput]: APITextInputComponent;
}

View File

@ -0,0 +1,31 @@
import type { ComponentType } from '../common';
import { BaseComponent } from './BaseComponent';
export type APISelectMenuComponentTypes =
| ComponentType.ChannelSelect
| ComponentType.MentionableSelect
| ComponentType.RoleSelect
| ComponentType.StringSelect
| ComponentType.UserSelect;
export class BaseSelectMenuComponent<T extends APISelectMenuComponentTypes> extends BaseComponent<T> {
get customId() {
return this.data.custom_id;
}
get disabed() {
return this.data.disabled;
}
get max() {
return this.data.max_values;
}
get min() {
return this.data.min_values;
}
get placeholder() {
return this.data.placeholder;
}
}

View File

@ -1,41 +1,54 @@
import type { import { Button, type ButtonStylesForID } from '../builders';
APIButtonComponentWithCustomId, import type { ButtonStyle, ComponentType } from '../common';
APIButtonComponentWithURL, import { BaseComponent } from './BaseComponent';
APIMessageComponentEmoji,
ComponentType,
} from '../common';
import { ButtonStyle } from '../common';
import { BaseComponent } from '../structures/extra/BaseComponent';
export class LinkButtonComponent extends BaseComponent<ComponentType.Button> { export class LinkButtonComponent extends BaseComponent<ComponentType.Button> {
constructor(data: APIButtonComponentWithURL) { get style() {
super(data); return this.data.style as ButtonStyle.Link;
this.label = data.label;
this.emoji = data.emoji;
this.disabled = !!data.disabled;
this.url = data.url;
} }
style = ButtonStyle.Link; get url(): string {
label?: string; // @ts-ignore
emoji?: APIMessageComponentEmoji; return this.data.url;
disabled: boolean; }
url: string;
get label() {
return this.data.label;
}
get disabled() {
return this.data.disabled;
}
get emoji() {
return this.data.emoji;
}
toBuilder() {
return new Button<false>(this.data as never);
}
} }
export type ButtonStyleExludeLink = Exclude<ButtonStyle, ButtonStyle.Link>; export type ButtonStyleExludeLink = Exclude<ButtonStyle, ButtonStyle.Link>;
export class ButtonComponent extends BaseComponent<ComponentType.Button> { export class ButtonComponent extends BaseComponent<ComponentType.Button> {
constructor(data: APIButtonComponentWithCustomId) { get style() {
super(data); return this.data.style as ButtonStylesForID;
this.style = data.style;
this.label = data.label;
this.emoji = data.emoji;
this.disabled = !!data.disabled;
} }
style: ButtonStyleExludeLink; get label() {
label?: string; return this.data.label;
emoji?: APIMessageComponentEmoji; }
disabled: boolean;
get disabled() {
return this.data.disabled;
}
get emoji() {
return this.data.emoji;
}
toBuilder() {
return new Button<true>(this.data as never);
}
} }

View File

@ -1,12 +1,12 @@
import type { APIChannelSelectComponent, ChannelType, ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseSelectMenuComponent } from '../structures/extra/BaseSelectMenuComponent'; import { BaseSelectMenuComponent } from './BaseSelectMenuComponent';
export class ChannelSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.ChannelSelect> { export class ChannelSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.ChannelSelect> {
constructor(data: APIChannelSelectComponent) { get channelsTypes() {
super(data); return this.data.channel_types;
this.channelTypes = data.channel_types;
} }
channelTypes?: ChannelType[]; get defaultValues() {
return this.data.default_values;
}
} }

View File

@ -1,4 +1,8 @@
import type { ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseSelectMenuComponent } from '../structures/extra/BaseSelectMenuComponent'; import { BaseSelectMenuComponent } from './BaseSelectMenuComponent';
export class MentionableSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.MentionableSelect> {} export class MentionableSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.MentionableSelect> {
get defaultValues() {
return this.data.default_values;
}
}

View File

@ -1,4 +1,8 @@
import type { ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseSelectMenuComponent } from '../structures/extra/BaseSelectMenuComponent'; import { BaseSelectMenuComponent } from './BaseSelectMenuComponent';
export class RoleSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.RoleSelect> {} export class RoleSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.RoleSelect> {
get defaultValues() {
return this.data.default_values;
}
}

View File

@ -1,12 +1,8 @@
import type { APISelectMenuOption, APIStringSelectComponent, ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseSelectMenuComponent } from '../structures/extra/BaseSelectMenuComponent'; import { BaseSelectMenuComponent } from './BaseSelectMenuComponent';
export class StringSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.StringSelect> { export class StringSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.StringSelect> {
constructor(data: APIStringSelectComponent) { get options() {
super(data); return this.data.options;
this.options = data.options;
} }
options: APISelectMenuOption[];
} }

View File

@ -1,14 +1,36 @@
import type { APIModalComponent, APITextInputComponent, ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseComponent } from '../structures/extra/BaseComponent'; import { BaseComponent } from './BaseComponent';
export class TextInputComponent extends BaseComponent<ComponentType.TextInput> { export class TextInputComponent extends BaseComponent<ComponentType.TextInput> {
constructor(data: APITextInputComponent) { get customId() {
super(data); return this.data.custom_id;
this.customId = data.custom_id;
this.value = data.value!;
} }
customId: string; get value() {
value: string | APIModalComponent; return this.data.value;
}
get style() {
return this.data.style;
}
get label() {
return this.data.label;
}
get max() {
return this.data.max_length;
}
get min() {
return this.data.min_length;
}
get required() {
return this.data.required;
}
get placeholder() {
return this.data.placeholder;
}
} }

View File

@ -1,4 +1,8 @@
import type { ComponentType } from '../common'; import type { ComponentType } from '../common';
import { BaseSelectMenuComponent } from '../structures/extra/BaseSelectMenuComponent'; import { BaseSelectMenuComponent } from './BaseSelectMenuComponent';
export class UserSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.UserSelect> {} export class UserSelectMenuComponent extends BaseSelectMenuComponent<ComponentType.UserSelect> {
get defaultValues() {
return this.data.default_values;
}
}

View File

@ -1,6 +1,6 @@
import type { APIMessageActionRowComponent } from '../common'; import type { APIMessageActionRowComponent } from '../common';
import { ButtonStyle, ComponentType } from '../common'; import { ButtonStyle, ComponentType } from '../common';
import { BaseComponent } from '../structures/extra/BaseComponent'; import { BaseComponent } from './BaseComponent';
import { ButtonComponent, LinkButtonComponent } from './ButtonComponent'; import { ButtonComponent, LinkButtonComponent } from './ButtonComponent';
import { ChannelSelectMenuComponent } from './ChannelSelectMenuComponent'; import { ChannelSelectMenuComponent } from './ChannelSelectMenuComponent';
import { MentionableSelectMenuComponent } from './MentionableSelectMenuComponent'; import { MentionableSelectMenuComponent } from './MentionableSelectMenuComponent';

View File

@ -1,13 +0,0 @@
import type { APIBaseComponent, ComponentType } from '../../common';
export interface BaseComponent<T extends ComponentType> extends APIBaseComponent<T> {}
export class BaseComponent<T extends ComponentType> {
constructor(data: APIBaseComponent<T>) {
Object.assign(this, data);
}
toJSON() {
return { type: this.type };
}
}

View File

@ -1,23 +0,0 @@
import type { APIBaseSelectMenuComponent, ComponentType, Identify, ObjectToLower } from '../../common';
import { BaseComponent } from './BaseComponent';
export type APISelectMenuComponentTypes =
| ComponentType.ChannelSelect
| ComponentType.MentionableSelect
| ComponentType.RoleSelect
| ComponentType.StringSelect
| ComponentType.UserSelect;
export interface BaseSelectMenuComponent<T extends APISelectMenuComponentTypes>
extends BaseComponent<T>,
ObjectToLower<Identify<Omit<APIBaseSelectMenuComponent<APISelectMenuComponentTypes>, 'type'>>> {}
export class BaseSelectMenuComponent<T extends APISelectMenuComponentTypes> extends BaseComponent<T> {
constructor(data: APIBaseSelectMenuComponent<T>) {
super(data);
}
toJSON() {
return { ...this };
}
}