From 244ccc801eec39196d9f2ba34313d606ecd1c04d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 22:06:26 +0000 Subject: [PATCH] refactor(commands): share preview streaming migration logic --- src/commands/doctor-legacy-config.test.ts | 34 ++++++ src/commands/doctor-legacy-config.ts | 128 +++++++--------------- 2 files changed, 76 insertions(+), 86 deletions(-) create mode 100644 src/commands/doctor-legacy-config.test.ts diff --git a/src/commands/doctor-legacy-config.test.ts b/src/commands/doctor-legacy-config.test.ts new file mode 100644 index 00000000000..38e51757b21 --- /dev/null +++ b/src/commands/doctor-legacy-config.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { normalizeLegacyConfigValues } from "./doctor-legacy-config.js"; + +describe("normalizeLegacyConfigValues preview streaming aliases", () => { + it("normalizes telegram boolean streaming aliases to enum", () => { + const res = normalizeLegacyConfigValues({ + channels: { + telegram: { + streaming: false, + }, + }, + }); + + expect(res.config.channels?.telegram?.streaming).toBe("off"); + expect(res.config.channels?.telegram?.streamMode).toBeUndefined(); + expect(res.changes).toEqual(["Normalized channels.telegram.streaming boolean → enum (off)."]); + }); + + it("normalizes discord boolean streaming aliases to enum", () => { + const res = normalizeLegacyConfigValues({ + channels: { + discord: { + streaming: true, + }, + }, + }); + + expect(res.config.channels?.discord?.streaming).toBe("partial"); + expect(res.config.channels?.discord?.streamMode).toBeUndefined(); + expect(res.changes).toEqual([ + "Normalized channels.discord.streaming boolean → enum (partial).", + ]); + }); +}); diff --git a/src/commands/doctor-legacy-config.ts b/src/commands/doctor-legacy-config.ts index 91c1d5eaaba..c8043d5a7ad 100644 --- a/src/commands/doctor-legacy-config.ts +++ b/src/commands/doctor-legacy-config.ts @@ -97,54 +97,15 @@ export function normalizeLegacyConfigValues(cfg: OpenClawConfig): { return { entry: updated, changed }; }; - const normalizeTelegramStreamingAliases = (params: { + const normalizePreviewStreamingAliases = (params: { entry: Record; pathPrefix: string; + resolveStreaming: (entry: Record) => string; }): { entry: Record; changed: boolean } => { let updated = params.entry; const hadLegacyStreamMode = updated.streamMode !== undefined; const beforeStreaming = updated.streaming; - const resolved = resolveTelegramPreviewStreamMode(updated); - const shouldNormalize = - hadLegacyStreamMode || - typeof beforeStreaming === "boolean" || - (typeof beforeStreaming === "string" && beforeStreaming !== resolved); - if (!shouldNormalize) { - return { entry: updated, changed: false }; - } - - let changed = false; - if (beforeStreaming !== resolved) { - updated = { ...updated, streaming: resolved }; - changed = true; - } - if (hadLegacyStreamMode) { - const { streamMode: _ignored, ...rest } = updated; - updated = rest; - changed = true; - changes.push( - `Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`, - ); - } - if (typeof beforeStreaming === "boolean") { - changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`); - } else if (typeof beforeStreaming === "string" && beforeStreaming !== resolved) { - changes.push( - `Normalized ${params.pathPrefix}.streaming (${beforeStreaming}) → (${resolved}).`, - ); - } - - return { entry: updated, changed }; - }; - - const normalizeDiscordStreamingAliases = (params: { - entry: Record; - pathPrefix: string; - }): { entry: Record; changed: boolean } => { - let updated = params.entry; - const hadLegacyStreamMode = updated.streamMode !== undefined; - const beforeStreaming = updated.streaming; - const resolved = resolveDiscordPreviewStreamMode(updated); + const resolved = params.resolveStreaming(updated); const shouldNormalize = hadLegacyStreamMode || typeof beforeStreaming === "boolean" || @@ -229,6 +190,31 @@ export function normalizeLegacyConfigValues(cfg: OpenClawConfig): { return { entry: updated, changed }; }; + const normalizeStreamingAliasesForProvider = (params: { + provider: "telegram" | "slack" | "discord"; + entry: Record; + pathPrefix: string; + }): { entry: Record; changed: boolean } => { + if (params.provider === "telegram") { + return normalizePreviewStreamingAliases({ + entry: params.entry, + pathPrefix: params.pathPrefix, + resolveStreaming: resolveTelegramPreviewStreamMode, + }); + } + if (params.provider === "discord") { + return normalizePreviewStreamingAliases({ + entry: params.entry, + pathPrefix: params.pathPrefix, + resolveStreaming: resolveDiscordPreviewStreamMode, + }); + } + return normalizeSlackStreamingAliases({ + entry: params.entry, + pathPrefix: params.pathPrefix, + }); + }; + const normalizeProvider = (provider: "telegram" | "slack" | "discord") => { const channels = next.channels as Record | undefined; const rawEntry = channels?.[provider]; @@ -247,28 +233,13 @@ export function normalizeLegacyConfigValues(cfg: OpenClawConfig): { updated = base.entry; changed = base.changed; } - if (provider === "telegram") { - const streaming = normalizeTelegramStreamingAliases({ - entry: updated, - pathPrefix: `channels.${provider}`, - }); - updated = streaming.entry; - changed = changed || streaming.changed; - } else if (provider === "discord") { - const streaming = normalizeDiscordStreamingAliases({ - entry: updated, - pathPrefix: `channels.${provider}`, - }); - updated = streaming.entry; - changed = changed || streaming.changed; - } else if (provider === "slack") { - const streaming = normalizeSlackStreamingAliases({ - entry: updated, - pathPrefix: `channels.${provider}`, - }); - updated = streaming.entry; - changed = changed || streaming.changed; - } + const providerStreaming = normalizeStreamingAliasesForProvider({ + provider, + entry: updated, + pathPrefix: `channels.${provider}`, + }); + updated = providerStreaming.entry; + changed = changed || providerStreaming.changed; const rawAccounts = updated.accounts; if (isRecord(rawAccounts)) { @@ -289,28 +260,13 @@ export function normalizeLegacyConfigValues(cfg: OpenClawConfig): { accountEntry = res.entry; accountChanged = res.changed; } - if (provider === "telegram") { - const streaming = normalizeTelegramStreamingAliases({ - entry: accountEntry, - pathPrefix: `channels.${provider}.accounts.${accountId}`, - }); - accountEntry = streaming.entry; - accountChanged = accountChanged || streaming.changed; - } else if (provider === "discord") { - const streaming = normalizeDiscordStreamingAliases({ - entry: accountEntry, - pathPrefix: `channels.${provider}.accounts.${accountId}`, - }); - accountEntry = streaming.entry; - accountChanged = accountChanged || streaming.changed; - } else if (provider === "slack") { - const streaming = normalizeSlackStreamingAliases({ - entry: accountEntry, - pathPrefix: `channels.${provider}.accounts.${accountId}`, - }); - accountEntry = streaming.entry; - accountChanged = accountChanged || streaming.changed; - } + const accountStreaming = normalizeStreamingAliasesForProvider({ + provider, + entry: accountEntry, + pathPrefix: `channels.${provider}.accounts.${accountId}`, + }); + accountEntry = accountStreaming.entry; + accountChanged = accountChanged || accountStreaming.changed; if (accountChanged) { accounts[accountId] = accountEntry; accountsChanged = true;