Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Openclaw/extensions/twitch/src/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 6 kB image not shown  

Quelle  config.ts

  Sprache: JAVA
 

import {
  listCombinedAccountIds,
  normalizeAccountId,
  resolveNormalizedAccountEntry,
} from "openclaw/plugin-sdk/account-resolution";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { resolveTwitchToken, type TwitchTokenResolution } from "./token.js";
import type { TwitchAccountConfig } from "./types.js";
import { isAccountConfigured } from "./utils/twitch.js";

/**
 * Default account ID for Twitch
 */

export const DEFAULT_ACCOUNT_ID = "default";

export type ResolvedTwitchAccountContext = {
  accountId: string;
  account: TwitchAccountConfig | null;
  tokenResolution: TwitchTokenResolution;
  configured: boolean;
  availableAccountIds: string[];
};

/**
 * Get account config from core config
 *
 * Handles two patterns:
 * 1. Simplified single-account: base-level properties create implicit "default" account
 * 2. Multi-account: explicit accounts object
 *
 * For "default" account, base-level properties take precedence over accounts.default
 * For other accounts, only the accounts object is checked
 */

export function getAccountConfig(
  coreConfig: unknown,
  accountId: string,
): TwitchAccountConfig | null {
  if (!coreConfig || typeof coreConfig !== "object") {
    return null;
  }

  const cfg = coreConfig as OpenClawConfig;
  const normalizedAccountId = normalizeAccountId(accountId);
  const twitch = cfg.channels?.twitch;
  // Access accounts via unknown to handle union type (single-account vs multi-account)
  const twitchRaw = twitch as Record<string, unknown> | undefined;
  const accounts = twitchRaw?.accounts as Record<string, TwitchAccountConfig> | undefined;

  // For default account, check base-level config first
  if (normalizedAccountId === DEFAULT_ACCOUNT_ID) {
    const accountFromAccounts = resolveNormalizedAccountEntry(
      accounts,
      DEFAULT_ACCOUNT_ID,
      normalizeAccountId,
    );

    // Base-level properties that can form an implicit default account
    const baseLevel = {
      username: typeof twitchRaw?.username === "string" ? twitchRaw.username : undefined,
      accessToken: typeof twitchRaw?.accessToken === "string" ? twitchRaw.accessToken : undefined,
      clientId: typeof twitchRaw?.clientId === "string" ? twitchRaw.clientId : undefined,
      channel: typeof twitchRaw?.channel === "string" ? twitchRaw.channel : undefined,
      enabled: typeof twitchRaw?.enabled === "boolean" ? twitchRaw.enabled : undefined,
      allowFrom: Array.isArray(twitchRaw?.allowFrom) ? twitchRaw.allowFrom : undefined,
      allowedRoles: Array.isArray(twitchRaw?.allowedRoles) ? twitchRaw.allowedRoles : undefined,
      requireMention:
        typeof twitchRaw?.requireMention === "boolean" ? twitchRaw.requireMention : undefined,
      clientSecret:
        typeof twitchRaw?.clientSecret === "string" ? twitchRaw.clientSecret : undefined,
      refreshToken:
        typeof twitchRaw?.refreshToken === "string" ? twitchRaw.refreshToken : undefined,
      expiresIn: typeof twitchRaw?.expiresIn === "number" ? twitchRaw.expiresIn : undefined,
      obtainmentTimestamp:
        typeof twitchRaw?.obtainmentTimestamp === "number"
          ? twitchRaw.obtainmentTimestamp
          : undefined,
    };

    // Merge: base-level takes precedence over accounts.default
    const merged: Partial<TwitchAccountConfig> = {
      ...accountFromAccounts,
      ...baseLevel,
    } as Partial<TwitchAccountConfig>;

    // Only return if we have at least username
    if (merged.username) {
      return merged as TwitchAccountConfig;
    }

    // Fall through to accounts.default if no base-level username
    if (accountFromAccounts) {
      return accountFromAccounts;
    }

    return null;
  }

  // For non-default accounts, only check accounts object
  const account = resolveNormalizedAccountEntry(accounts, normalizedAccountId, normalizeAccountId);
  if (!account) {
    return null;
  }

  return account;
}

/**
 * List all configured account IDs
 *
 * Includes both explicit accounts and implicit "default" from base-level config
 */

export function listAccountIds(cfg: OpenClawConfig): string[] {
  const twitch = cfg.channels?.twitch;
  // Access accounts via unknown to handle union type (single-account vs multi-account)
  const twitchRaw = twitch as Record<string, unknown> | undefined;
  const accountMap = twitchRaw?.accounts as Record<string, unknown> | undefined;

  // Add implicit "default" if base-level config exists and "default" not already present
  const hasBaseLevelConfig =
    twitchRaw &&
    (typeof twitchRaw.username === "string" ||
      typeof twitchRaw.accessToken === "string" ||
      typeof twitchRaw.channel === "string");

  return listCombinedAccountIds({
    configuredAccountIds: Object.keys(accountMap ?? {}).map((accountId) =>
      normalizeAccountId(accountId),
    ),
    implicitAccountId: hasBaseLevelConfig ? DEFAULT_ACCOUNT_ID : undefined,
  });
}

export function resolveDefaultTwitchAccountId(cfg: OpenClawConfig): string {
  const preferredRaw =
    typeof cfg.channels?.twitch?.defaultAccount === "string"
      ? cfg.channels.twitch.defaultAccount.trim()
      : "";
  const preferred = preferredRaw ? normalizeAccountId(preferredRaw) : "";
  const ids = listAccountIds(cfg);
  if (preferred && ids.includes(preferred)) {
    return preferred;
  }
  if (ids.includes(DEFAULT_ACCOUNT_ID)) {
    return DEFAULT_ACCOUNT_ID;
  }
  return ids[0] ?? DEFAULT_ACCOUNT_ID;
}

export function resolveTwitchAccountContext(
  cfg: OpenClawConfig,
  accountId?: string | null,
): ResolvedTwitchAccountContext {
  const resolvedAccountId = accountId?.trim()
    ? normalizeAccountId(accountId)
    : resolveDefaultTwitchAccountId(cfg);
  const account = getAccountConfig(cfg, resolvedAccountId);
  const tokenResolution = resolveTwitchToken(cfg, { accountId: resolvedAccountId });
  return {
    accountId: resolvedAccountId,
    account,
    tokenResolution,
    configured: account ? isAccountConfigured(account, tokenResolution.token) : false,
    availableAccountIds: listAccountIds(cfg),
  };
}

export function resolveTwitchSnapshotAccountId(
  cfg: OpenClawConfig,
  account: TwitchAccountConfig,
): string {
  const twitch = (cfg as Record<string, unknown>).channels as Record<string, unknown> | undefined;
  const twitchCfg = twitch?.twitch as Record<string, unknown> | undefined;
  const accountMap = (twitchCfg?.accounts as Record<string, unknown> | undefined) ?? {};
  return (
    Object.entries(accountMap).find(([, value]) => value === account)?.[0] ?? DEFAULT_ACCOUNT_ID
  );
}

Messung V0.5 in Prozent
C=98 H=91 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.