Files
DeskClaw/electron/utils/channel-alias.ts
2026-04-08 19:16:15 +08:00

53 lines
1.9 KiB
TypeScript

const BLOCKED_OBJECT_KEYS = new Set(['__proto__', 'prototype', 'constructor']);
const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
const INVALID_CHARS_RE = /[^a-z0-9_-]+/g;
const LEADING_DASH_RE = /^-+/;
const TRAILING_DASH_RE = /-+$/;
export const UI_WECHAT_CHANNEL_TYPE = 'wechat';
export const OPENCLAW_WECHAT_CHANNEL_TYPE = 'openclaw-weixin';
export type QrChannelEvent = 'qr' | 'success' | 'error';
export function toOpenClawChannelType(channelType: string): string {
return channelType === UI_WECHAT_CHANNEL_TYPE ? OPENCLAW_WECHAT_CHANNEL_TYPE : channelType;
}
export function toUiChannelType(channelType: string): string {
return channelType === OPENCLAW_WECHAT_CHANNEL_TYPE ? UI_WECHAT_CHANNEL_TYPE : channelType;
}
export function isWechatChannelType(channelType: string | null | undefined): boolean {
return channelType === UI_WECHAT_CHANNEL_TYPE || channelType === OPENCLAW_WECHAT_CHANNEL_TYPE;
}
export function buildQrChannelEventName(channelType: string, event: QrChannelEvent): string {
return `channel:${toUiChannelType(channelType)}-${event}`;
}
function canonicalizeAccountId(value: string): string {
if (VALID_ID_RE.test(value)) return value.toLowerCase();
return value
.toLowerCase()
.replace(INVALID_CHARS_RE, '-')
.replace(LEADING_DASH_RE, '')
.replace(TRAILING_DASH_RE, '')
.slice(0, 64);
}
export function normalizeOpenClawAccountId(value: string | null | undefined, fallback = 'default'): string {
const trimmed = (value ?? '').trim();
if (!trimmed) return fallback;
const normalized = canonicalizeAccountId(trimmed);
if (!normalized || BLOCKED_OBJECT_KEYS.has(normalized)) {
return fallback;
}
return normalized;
}
export function isCanonicalOpenClawAccountId(value: string | null | undefined): boolean {
const trimmed = (value ?? '').trim();
if (!trimmed) return false;
return normalizeOpenClawAccountId(trimmed, '') === trimmed;
}