mirror of
https://github.com/jaronpate/unicord.git
synced 2026-10-18 21:47:40 +00:00
121 lines
4.5 KiB
TypeScript
121 lines
4.5 KiB
TypeScript
import { UnicordChannelsCache, UnicordGuildsCache, UnicordUsersCache } from './caches';
|
|
import { UnicordCommandManager } from './commandManager';
|
|
import type { UnicordCommandContext } from './context';
|
|
import { UnicordDiscordAPI } from './discordAPI';
|
|
import { UnicordEventProcessor } from './eventProcessor';
|
|
import { UnicordGatewayManager } from './gatewayManager';
|
|
import { hydrate } from './hydrator';
|
|
import type {
|
|
UnicordCommandOptions,
|
|
UnicordConfig,
|
|
UnicordConfigWithDefaults,
|
|
UnicordEventContext,
|
|
UnicordEventHandler,
|
|
UnicordHandler,
|
|
} from './types/common';
|
|
import { Intent, UnicordEventType } from './types/common';
|
|
import type { DiscordMessage } from './types/message';
|
|
import { Message } from './types/message';
|
|
import { defaults } from './utils';
|
|
|
|
const UNICORD_CONFIG_DEFAULTS = {
|
|
intents: [Intent.DEFAULT],
|
|
};
|
|
|
|
export class Unicord {
|
|
readonly config: UnicordConfigWithDefaults;
|
|
readonly discordAPI: UnicordDiscordAPI;
|
|
private readonly eventProcessor: UnicordEventProcessor;
|
|
private readonly gatewayManager: UnicordGatewayManager;
|
|
// TODO: split command management out of the event processor
|
|
// This way we can properly store and manage registered commands
|
|
// This will enable features like command listing, removal, autogenerated help, etc.
|
|
// We can also go registration with the Discord API here
|
|
// This will also eliminate the weird helper methods on the Unicord class itself
|
|
private readonly commandManager: UnicordCommandManager;
|
|
readonly caches: {
|
|
readonly users: UnicordUsersCache;
|
|
readonly channels: UnicordChannelsCache;
|
|
readonly guilds: UnicordGuildsCache;
|
|
};
|
|
|
|
constructor(userConfig: UnicordConfig = {}) {
|
|
this.config = defaults(userConfig, UNICORD_CONFIG_DEFAULTS) as UnicordConfigWithDefaults;
|
|
this.discordAPI = new UnicordDiscordAPI(this);
|
|
this.eventProcessor = new UnicordEventProcessor(this);
|
|
this.gatewayManager = new UnicordGatewayManager(this);
|
|
this.commandManager = new UnicordCommandManager(this, this.eventProcessor);
|
|
this.caches = {
|
|
users: new UnicordUsersCache(this),
|
|
channels: new UnicordChannelsCache(this),
|
|
guilds: new UnicordGuildsCache(this),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Hydrates a given data object based on the provided expectations.
|
|
*
|
|
* @param data - The data object to be hydrated. Can be of type `Context` or `Message`.
|
|
* @param expectations - An array of expectations that specify what properties should be hydrated.
|
|
*
|
|
* @returns A promise that resolves to the hydrated data object.
|
|
*
|
|
* @throws Will throw an error if an expectation cannot be resolved.
|
|
*/
|
|
get hydrate() {
|
|
return hydrate.bind(null, this);
|
|
}
|
|
|
|
private __onEvent<Options extends UnicordCommandOptions>(
|
|
type: UnicordEventType,
|
|
event: string,
|
|
handler: UnicordHandler<Options>,
|
|
) {
|
|
return this.eventProcessor.register(`${type}:${event}`, handler);
|
|
}
|
|
|
|
emit(type: UnicordEventType, event: string, context: UnicordCommandContext | UnicordEventContext, args: any[]) {
|
|
this.eventProcessor.emit(`${type}:${event}`, context, args);
|
|
}
|
|
|
|
// TODO: type signature from registerChatCommand needs to transfer to here
|
|
get registerChatCommand() {
|
|
return this.commandManager.registerChatCommand;
|
|
}
|
|
|
|
// TODO: type signature from registerApplicationCommand needs to transfer to here
|
|
get registerApplicationCommand() {
|
|
return this.commandManager.registerApplicationCommand;
|
|
}
|
|
|
|
// TODO: should have a different signature for events that are not commands
|
|
onEvent(event: string, handler: UnicordEventHandler): this {
|
|
this.__onEvent(UnicordEventType.SystemEvent, event, handler);
|
|
return this;
|
|
}
|
|
|
|
sendMessage = async (channel_id: string, message: Message | string) => {
|
|
if (typeof message === 'string') {
|
|
message = new Message().setContent(message);
|
|
}
|
|
|
|
return Message.fromDiscord(
|
|
await this.discordAPI.post<DiscordMessage>(`/channels/${channel_id}/messages`, message.toJSON()),
|
|
);
|
|
};
|
|
|
|
login(token: string | undefined = this.config.token) {
|
|
if (token === null || token === undefined) {
|
|
throw new Error(
|
|
'You must provide a token to login. Either in the Unicord config or when calling `login()`',
|
|
);
|
|
}
|
|
|
|
this.config.token = token;
|
|
|
|
this.gatewayManager.connect();
|
|
}
|
|
}
|
|
|
|
export * from './types/common';
|