mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 16:10:23 +00:00
refactor: move built-in channel normalization to ids
This commit is contained in:
committed by
Peter Steinberger
parent
57ee3d9673
commit
8bd3067e69
@@ -99,39 +99,10 @@ function buildChatChannelMetaById(): Record<ChatChannelId, ChatChannelMeta> {
|
||||
|
||||
const CHAT_CHANNEL_META = buildChatChannelMetaById();
|
||||
|
||||
export const CHAT_CHANNEL_ALIASES: Record<string, ChatChannelId> = Object.freeze(
|
||||
Object.fromEntries(
|
||||
Object.values(CHAT_CHANNEL_META)
|
||||
.flatMap((meta) =>
|
||||
(meta.aliases ?? []).map((alias) => [alias.trim().toLowerCase(), meta.id] as const),
|
||||
)
|
||||
.filter(([alias]) => alias.length > 0)
|
||||
.toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
),
|
||||
) as Record<string, ChatChannelId>;
|
||||
|
||||
function normalizeChannelKey(raw?: string | null): string | undefined {
|
||||
const normalized = raw?.trim().toLowerCase();
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
export function listChatChannels(): ChatChannelMeta[] {
|
||||
return CHAT_CHANNEL_ORDER.map((id) => CHAT_CHANNEL_META[id]);
|
||||
}
|
||||
|
||||
export function listChatChannelAliases(): string[] {
|
||||
return Object.keys(CHAT_CHANNEL_ALIASES);
|
||||
}
|
||||
|
||||
export function getChatChannelMeta(id: ChatChannelId): ChatChannelMeta {
|
||||
return CHAT_CHANNEL_META[id];
|
||||
}
|
||||
|
||||
export function normalizeChatChannelId(raw?: string | null): ChatChannelId | null {
|
||||
const normalized = normalizeChannelKey(raw);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
const resolved = CHAT_CHANNEL_ALIASES[normalized] ?? normalized;
|
||||
return CHAT_CHANNEL_ORDER.includes(resolved) ? resolved : null;
|
||||
}
|
||||
|
||||
57
src/channels/ids.test.ts
Normal file
57
src/channels/ids.test.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { listBundledPluginMetadata } from "../plugins/bundled-plugin-metadata.js";
|
||||
import {
|
||||
CHAT_CHANNEL_ALIASES,
|
||||
CHAT_CHANNEL_ORDER,
|
||||
normalizeChatChannelId,
|
||||
type ChatChannelId,
|
||||
} from "./ids.js";
|
||||
|
||||
function collectBundledChatChannelAliases(): Record<string, ChatChannelId> {
|
||||
const aliases = new Map<string, ChatChannelId>();
|
||||
|
||||
for (const entry of listBundledPluginMetadata({
|
||||
includeChannelConfigs: true,
|
||||
includeSyntheticChannelConfigs: false,
|
||||
})) {
|
||||
const channel =
|
||||
entry.packageManifest && "channel" in entry.packageManifest
|
||||
? entry.packageManifest.channel
|
||||
: undefined;
|
||||
const rawId = channel?.id?.trim();
|
||||
if (!rawId || !CHAT_CHANNEL_ORDER.includes(rawId as ChatChannelId)) {
|
||||
continue;
|
||||
}
|
||||
const channelId = rawId as ChatChannelId;
|
||||
if (!channel) {
|
||||
continue;
|
||||
}
|
||||
for (const alias of channel.aliases ?? []) {
|
||||
const normalizedAlias = alias.trim().toLowerCase();
|
||||
if (!normalizedAlias) {
|
||||
continue;
|
||||
}
|
||||
aliases.set(normalizedAlias, channelId);
|
||||
}
|
||||
}
|
||||
|
||||
return Object.fromEntries(
|
||||
[...aliases.entries()].toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
) as Record<string, ChatChannelId>;
|
||||
}
|
||||
|
||||
describe("channel ids", () => {
|
||||
it("normalizes built-in aliases + trims whitespace", () => {
|
||||
expect(normalizeChatChannelId(" imsg ")).toBe("imessage");
|
||||
expect(normalizeChatChannelId("gchat")).toBe("googlechat");
|
||||
expect(normalizeChatChannelId("google-chat")).toBe("googlechat");
|
||||
expect(normalizeChatChannelId("internet-relay-chat")).toBe("irc");
|
||||
expect(normalizeChatChannelId("telegram")).toBe("telegram");
|
||||
expect(normalizeChatChannelId("web")).toBeNull();
|
||||
expect(normalizeChatChannelId("nope")).toBeNull();
|
||||
});
|
||||
|
||||
it("matches bundled built-in channel alias metadata", () => {
|
||||
expect(CHAT_CHANNEL_ALIASES).toEqual(collectBundledChatChannelAliases());
|
||||
});
|
||||
});
|
||||
@@ -16,3 +16,32 @@ export const CHAT_CHANNEL_ORDER = [
|
||||
export type ChatChannelId = (typeof CHAT_CHANNEL_ORDER)[number];
|
||||
|
||||
export const CHANNEL_IDS = [...CHAT_CHANNEL_ORDER] as const;
|
||||
|
||||
const BUILT_IN_CHAT_CHANNEL_ALIAS_ENTRIES = [
|
||||
["gchat", "googlechat"],
|
||||
["google-chat", "googlechat"],
|
||||
["imsg", "imessage"],
|
||||
["internet-relay-chat", "irc"],
|
||||
] as const satisfies ReadonlyArray<readonly [string, ChatChannelId]>;
|
||||
|
||||
export const CHAT_CHANNEL_ALIASES: Record<string, ChatChannelId> = Object.freeze(
|
||||
Object.fromEntries(BUILT_IN_CHAT_CHANNEL_ALIAS_ENTRIES),
|
||||
) as Record<string, ChatChannelId>;
|
||||
|
||||
function normalizeChannelKey(raw?: string | null): string | undefined {
|
||||
const normalized = raw?.trim().toLowerCase();
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
export function listChatChannelAliases(): string[] {
|
||||
return Object.keys(CHAT_CHANNEL_ALIASES);
|
||||
}
|
||||
|
||||
export function normalizeChatChannelId(raw?: string | null): ChatChannelId | null {
|
||||
const normalized = normalizeChannelKey(raw);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
const resolved = CHAT_CHANNEL_ALIASES[normalized] ?? normalized;
|
||||
return CHAT_CHANNEL_ORDER.includes(resolved) ? resolved : null;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
formatChannelSelectionLine,
|
||||
listChatChannels,
|
||||
normalizeChatChannelId,
|
||||
} from "./registry.js";
|
||||
import { formatChannelSelectionLine, listChatChannels } from "./registry.js";
|
||||
|
||||
describe("channel registry helpers", () => {
|
||||
it("normalizes aliases + trims whitespace", () => {
|
||||
expect(normalizeChatChannelId(" imsg ")).toBe("imessage");
|
||||
expect(normalizeChatChannelId("gchat")).toBe("googlechat");
|
||||
expect(normalizeChatChannelId("google-chat")).toBe("googlechat");
|
||||
expect(normalizeChatChannelId("internet-relay-chat")).toBe("irc");
|
||||
expect(normalizeChatChannelId("telegram")).toBe("telegram");
|
||||
expect(normalizeChatChannelId("web")).toBeNull();
|
||||
expect(normalizeChatChannelId("nope")).toBeNull();
|
||||
});
|
||||
|
||||
it("keeps Telegram first in the default order", () => {
|
||||
const channels = listChatChannels();
|
||||
expect(channels[0]?.id).toBe("telegram");
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { getActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { getChatChannelMeta, listChatChannels, type ChatChannelMeta } from "./chat-meta.js";
|
||||
import {
|
||||
CHANNEL_IDS,
|
||||
CHAT_CHANNEL_ALIASES,
|
||||
getChatChannelMeta,
|
||||
CHAT_CHANNEL_ORDER,
|
||||
listChatChannelAliases,
|
||||
listChatChannels,
|
||||
normalizeChatChannelId,
|
||||
type ChatChannelMeta,
|
||||
} from "./chat-meta.js";
|
||||
import { CHANNEL_IDS, CHAT_CHANNEL_ORDER, type ChatChannelId } from "./ids.js";
|
||||
type ChatChannelId,
|
||||
} from "./ids.js";
|
||||
import type { ChannelId, ChannelMeta } from "./plugins/types.js";
|
||||
export { CHANNEL_IDS, CHAT_CHANNEL_ORDER } from "./ids.js";
|
||||
export type { ChatChannelId } from "./ids.js";
|
||||
|
||||
@@ -16,7 +16,7 @@ vi.mock("node:fs", async () => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../channels/registry.js", () => ({
|
||||
vi.mock("../channels/ids.js", () => ({
|
||||
CHAT_CHANNEL_ORDER: ["telegram", "discord"],
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { CHAT_CHANNEL_ORDER } from "../channels/registry.js";
|
||||
import { CHAT_CHANNEL_ORDER } from "../channels/ids.js";
|
||||
|
||||
function dedupe(values: string[]): string[] {
|
||||
const seen = new Set<string>();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeChatChannelId } from "../../../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../../../channels/ids.js";
|
||||
import type { OpenClawConfig } from "../../../config/config.js";
|
||||
import { readChannelAllowFromStore } from "../../../pairing/pairing-store.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeChatChannelId } from "../../../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../../../channels/ids.js";
|
||||
import { listRouteBindings } from "../../../config/bindings.js";
|
||||
import type { OpenClawConfig } from "../../../config/config.js";
|
||||
import {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import path from "node:path";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { CHANNEL_IDS } from "../channels/ids.js";
|
||||
import { normalizeChatChannelId } from "../channels/chat-meta.js";
|
||||
import { CHANNEL_IDS, normalizeChatChannelId } from "../channels/ids.js";
|
||||
import { withBundledPluginAllowlistCompat } from "../plugins/bundled-compat.js";
|
||||
import { listBundledWebSearchPluginIds } from "../plugins/bundled-web-search-ids.js";
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../channels/ids.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { defaultSlotIdForKey, hasKind } from "./slots.js";
|
||||
import type { PluginKind, PluginOrigin } from "./types.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../channels/ids.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensurePluginAllowlisted } from "../config/plugins-allowlist.js";
|
||||
import { setPluginEnabledInConfig } from "./toggle-config.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../channels/ids.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
export function setPluginEnabledInConfig(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../channels/ids.js";
|
||||
import { listRouteBindings } from "../config/bindings.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { AgentRouteBinding } from "../config/types.agents.js";
|
||||
|
||||
Reference in New Issue
Block a user