Skip to content
GitHub

MeoCord

function in meocord/decorator Since 4.0.0

MeoCord<
  const G extends readonly unknown[] = [],
  const I extends readonly unknown[] = [],
  const F extends readonly unknown[] = [],
>(
  options: MeoCordOptions<G, I, F>,
): (target: any, propertyKey?: string | symbol) => void

Declares the application class: its controllers, services, client options and what applies to every handler.

Put it on one class, the one main.ts passes to MeoCordFactory.create(). What the process needs before this class is read, the token, build and sharding, belongs in meocord.config.ts instead.

Parameters

NameTypeDefaultSinceDescription
optionsMeoCordOptions<G, I, F>

The app's controllers, client options and the rest; see MeoCordOptions.

options.controllersServiceIdentifier[]4.1.0

Controllers to register.

options.clientOptionsClientOptions4.1.0

Options for the discord.js Client, such as its intents and partials. The shards it runs as are set in meocord.config.ts, under sharding.

options.activities?ActivityOptions[]4.1.0

Activities the bot rotates through, in order: the first is shown once the bot is ready, and the next every 10 seconds, starting again after the last. Without them MeoCord leaves the bot's presence as the app sets it.

options.services?ServiceIdentifier[]4.1.0

Services to register that no controller depends on.

options.providers?Provider[]4.1.0

Values classes inject by token with @Inject: { provide, useValue }, { provide, useClass }, or { provide, useFactory, inject? }, whose factory may return a promise, awaited before login. A token is a class, a string, a symbol or a createToken token. Provided values run their onReady and onShutdown hooks, in dependency order with the services.

options.guards?{ [K in keyof G]: CheckedEntry< G[K], new (...args: any[]) => GuardInterface > }4.1.0

Guards run before every dispatched handler, ahead of the controller's and the method's own guards: guard classes, or { provide, params? }. They also run before the built-in help and a parent command's list of subcommands answer a message. A controller method called directly runs only its own guards.

options.interceptors?{ [K in keyof I]: CheckedEntry< I[K], new ( ...args: any[] ) => InterceptorInterface > }4.1.0

Interceptors run around every dispatched handler except autocomplete, outside the controller's and the method's own. A controller method called directly runs none.

options.filters?{ [K in keyof F]: CheckedEntry< F[K], new ( ...args: any[] ) => ExceptionFilter<any> > }4.1.0

Exception filters tried after the method's and the controller's, and for errors outside any handler, such as CommandNotFoundError.

options.i18n?Translator<any>4.1.0

The translator createTranslator made, injected as Translator wherever a class asks for one.

options.cooldownStore?new (...args: any[]) => CooldownStore4.1.0

Where @Cooldown counts calls, in place of this process's memory: a class extending CooldownStore, resolved like a service so it can inject its client.

options.cooldownStoreFailure?CooldownStoreFailure'deny'4.1.0

What a call with a cooldown gets when the store throws, rejects or does not answer in time: 'deny', the default, refuses it with CooldownStoreError, which the fallback answers privately (a message command's only with messages.dmOnError); 'allow' runs it uncounted. Either way the failure is logged once per outage, which ends when the store answers 30 seconds or more after its last failure. Under 'deny', a call the store counts after the timeout is given back through its verdict's release, so the refused caller loses no use; under 'allow' that late count is the call's own.

options.cooldownStoreTimeoutMs?number10004.1.0

How long a call waits for the cooldown store before it counts as a failure, in milliseconds, at most 2147483647.

options.presenter?new (...args: any[]) => ResponsePresenter4.1.0

The ResponsePresenter that styles loading and error views, and, with its messageError, a message command's error replies, resolved once from the container. Without one, MeoCord's own styling is used.

options.messages?MessageCommandOptions4.1.0

How message commands start and match across the app: the prefix, a mention of the bot, mention: 'only', the app's own param types, how usage replies look, and the built-in help.

options.observers?(new (...args: any[]) => DispatchObserver)[]4.1.0

@Observer classes told about every dispatched call once it has settled, with its outcome and duration, in the order listed. The call never waits for them.

options.warnUnanswered?booleanon in development (`NODE_ENV` is `development`, as under `meocord start --dev`), off otherwise4.1.0

Warns, once per handler, when a handler, or an interceptor that returns without running it, finishes without answering its interaction, or defers it and never follows up, which leaves the user waiting.

options.theme?RootTheme4.1.0

The app's theme: the roles it changes from MeoCord's defaults, and every role the app adds. It applies to every handler, beneath each @UseTheme; code reads it with useTheme(). Each token is checked as the decorator applies, so a bad one stops the bot before it logs in.

options.themeFor?| ThemeResolvers | (new (...args: any[]) => ThemeResolver)4.1.0

Themes by where a call comes from: guild for a server's, over the handler's, and user for a user's, over the server's, in a server or a DM. Each returns part of a theme or undefined, at once or as a promise, and is looked up while @Defer acknowledges, before the guards. A result that is not a valid theme is left out, with a warning once per server or user; a resolver that fails or passes its timeout leaves its theme out of the call, logged once until it answers again. A class implementing ThemeResolver does the same with the app's services, resolved from its container.

options.themeCache?{ ttlSeconds?: number maxGuilds?: number maxUsers?: number }4.1.0

How long themeFor's results are kept (ttlSeconds, 300 unless set) and how many (maxGuilds, 10,000, and maxUsers, 50,000), the oldest dropped first. Inject ThemeCache to clear one sooner.

options.themeForTimeoutMs?number10004.1.0

How long a call waits for a themeFor resolver, in milliseconds.

Returns

Returns a property decorator.

(target: any, propertyKey?: string | symbol) => void

Examples

TypeScript
@Controller()
class PingController {
  @Command('ping', CommandType.SLASH)
  async ping(interaction: ChatInputCommandInteraction) {
    await respond(interaction).send('Pong!')
  }
}

@MeoCord({ controllers: [PingController], clientOptions: { intents: [GatewayIntentBits.Guilds] } })
class App {}