import { RequestClient } from "@buape/carbon"; import { loadConfig } from "../config/config.js"; import { createDiscordRetryRunner, type RetryRunner } from "../infra/retry-policy.js"; import type { RetryConfig } from "../infra/retry.js"; import { resolveDiscordAccount } from "./accounts.js"; import { normalizeDiscordToken } from "./token.js"; export type DiscordClientOpts = { token?: string; accountId?: string; rest?: RequestClient; retry?: RetryConfig; verbose?: boolean; }; function resolveToken(params: { explicit?: string; accountId: string; fallbackToken?: string }) { const explicit = normalizeDiscordToken(params.explicit); if (explicit) { return explicit; } const fallback = normalizeDiscordToken(params.fallbackToken); if (!fallback) { throw new Error( `Discord bot token missing for account "${params.accountId}" (set discord.accounts.${params.accountId}.token or DISCORD_BOT_TOKEN for default).`, ); } return fallback; } function resolveRest(token: string, rest?: RequestClient) { return rest ?? new RequestClient(token); } export function createDiscordRestClient(opts: DiscordClientOpts, cfg = loadConfig()) { const account = resolveDiscordAccount({ cfg, accountId: opts.accountId }); const token = resolveToken({ explicit: opts.token, accountId: account.accountId, fallbackToken: account.token, }); const rest = resolveRest(token, opts.rest); return { token, rest, account }; } export function createDiscordClient( opts: DiscordClientOpts, cfg = loadConfig(), ): { token: string; rest: RequestClient; request: RetryRunner } { const { token, rest, account } = createDiscordRestClient(opts, cfg); const request = createDiscordRetryRunner({ retry: opts.retry, configRetry: account.config.retry, verbose: opts.verbose, }); return { token, rest, request }; } export function resolveDiscordRest(opts: DiscordClientOpts) { return createDiscordRestClient(opts).rest; }