Ctrl K
ComunidadGuías…

chatd/src/configuration.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
export type MattermostConfiguration = {
  baseURL: string;
  botToken: string;
  actionCallbackURL: string | undefined;
  adminToken: string | undefined;
};

export type BuzzConfiguration = {
  relayURL: string;
  privateKeyHex: string;
  accountLinksPath: string | undefined;
  authTagJSON: string | undefined;
};

export type ChatdConfiguration = {
  botUserName: string;
  blueclawBaseURL: string;
  blueclawIngressURL: string | undefined;
  relayInboundURL: string | undefined;
  admindBaseURL: string | undefined;
  listenPort: number;
  listenHostname: string;
  stateDirectory?: string;
  mattermost: MattermostConfiguration | undefined;
  buzz: BuzzConfiguration | undefined;
};

export function loadConfiguration(environment: Record<string, string | undefined>): ChatdConfiguration {
  const configuration: ChatdConfiguration = {
    botUserName: requireValue(environment, 'CHATD_BOT_USER_NAME'),
    blueclawBaseURL: trimTrailingSlash(
      environment['CHATD_BLUECLAW_BASE_URL']?.trim() ||
        deriveBaseURL(environment['CHATD_BLUECLAW_INGRESS_URL']) ||
        'http://127.0.0.1:8080',
    ),
    blueclawIngressURL: environment['CHATD_BLUECLAW_INGRESS_URL']?.trim() || undefined,
    relayInboundURL: environment['CHATD_RELAY_INBOUND_URL']?.trim() || undefined,
    admindBaseURL: environment['CHATD_ADMIND_BASE_URL']?.trim() || undefined,
    listenPort: parseListenPort(environment['CHATD_LISTEN_PORT']),
    listenHostname: environment['CHATD_LISTEN_HOSTNAME']?.trim() || '127.0.0.1',
    stateDirectory: environment['CHATD_STATE_DIRECTORY']?.trim() || undefined,
    mattermost: loadMattermostConfiguration(environment),
    buzz: loadBuzzConfiguration(environment),
  };
  if (!configuration.mattermost && !configuration.buzz) {
    throw new Error('chatd needs at least one platform: set CHATD_MATTERMOST_* or CHATD_BUZZ_* variables');
  }
  if (configuration.mattermost && !configuration.blueclawIngressURL) {
    throw new Error('CHATD_BLUECLAW_INGRESS_URL is required when mattermost is enabled');
  }
  return configuration;
}

function loadMattermostConfiguration(environment: Record<string, string | undefined>): MattermostConfiguration | undefined {
  const baseURL = environment['CHATD_MATTERMOST_BASE_URL']?.trim();
  if (!baseURL) return undefined;
  return {
    baseURL,
    botToken: requireValue(environment, 'CHATD_MATTERMOST_BOT_TOKEN'),
    actionCallbackURL: environment['CHATD_ACTION_CALLBACK_URL'],
    adminToken: environment['CHATD_MATTERMOST_ADMIN_TOKEN']?.trim() || undefined,
  };
}

function loadBuzzConfiguration(environment: Record<string, string | undefined>): BuzzConfiguration | undefined {
  const relayURL = environment['CHATD_BUZZ_RELAY_URL']?.trim();
  if (!relayURL) return undefined;
  const privateKeyHex = requireValue(environment, 'CHATD_BUZZ_PRIVATE_KEY').toLowerCase();
  if (!/^[0-9a-f]{64}$/.test(privateKeyHex)) {
    throw new Error('CHATD_BUZZ_PRIVATE_KEY must be 64 hex characters');
  }
  return {
    relayURL,
    privateKeyHex,
    accountLinksPath: environment['CHATD_BUZZ_ACCOUNT_LINKS_PATH']?.trim() || undefined,
    authTagJSON: environment['CHATD_BUZZ_AUTH_TAG']?.trim() || undefined,
  };
}


function deriveBaseURL(ingressURL: string | undefined): string | undefined {
  const trimmed = ingressURL?.trim();
  if (!trimmed) return undefined;
  try {
    return new URL(trimmed).origin;
  } catch {
    return undefined;
  }
}

function trimTrailingSlash(value: string): string {
  return value.endsWith('/') ? value.slice(0, -1) : value;
}

function requireValue(environment: Record<string, string | undefined>, key: string): string {
  const value = environment[key]?.trim();
  if (!value) throw new Error(`${key} is not configured`);
  return value;
}

function parseListenPort(value: string | undefined): number {
  const port = Number(value ?? '18090');
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error('CHATD_LISTEN_PORT must be a valid TCP port');
  }
  return port;
}