From 8407eeb33c15767156963f58836538451d89d8b0 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 18 Feb 2026 03:17:20 +0000 Subject: [PATCH] refactor: extract shared string normalization helpers --- src/channels/plugins/group-mentions.ts | 15 +++------------ src/config/sessions/group.ts | 9 ++------- src/imessage/monitor/runtime.ts | 3 ++- src/shared/string-normalization.ts | 17 +++++++++++++++++ src/slack/monitor/allow-list.ts | 17 ++++++++--------- 5 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 src/shared/string-normalization.ts diff --git a/src/channels/plugins/group-mentions.ts b/src/channels/plugins/group-mentions.ts index 4c91fc7eb..f52a58c0a 100644 --- a/src/channels/plugins/group-mentions.ts +++ b/src/channels/plugins/group-mentions.ts @@ -9,6 +9,7 @@ import type { GroupToolPolicyBySenderConfig, GroupToolPolicyConfig, } from "../../config/types.tools.js"; +import { normalizeHyphenSlug } from "../../shared/string-normalization.js"; import { resolveSlackAccount } from "../../slack/accounts.js"; type GroupMentionParams = { @@ -38,16 +39,6 @@ function normalizeDiscordSlug(value?: string | null) { return text; } -function normalizeSlackSlug(raw?: string | null) { - const trimmed = raw?.trim().toLowerCase() ?? ""; - if (!trimmed) { - return ""; - } - const dashed = trimmed.replace(/\s+/g, "-"); - const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-"); - return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); -} - function parseTelegramGroupId(value?: string | null) { const raw = value?.trim() ?? ""; if (!raw) { @@ -231,7 +222,7 @@ export function resolveSlackGroupRequireMention(params: GroupMentionParams): boo const channelId = params.groupId?.trim(); const groupChannel = params.groupChannel; const channelName = groupChannel?.replace(/^#/, ""); - const normalizedName = normalizeSlackSlug(channelName); + const normalizedName = normalizeHyphenSlug(channelName); const candidates = [ channelId ?? "", channelName ? `#${channelName}` : "", @@ -363,7 +354,7 @@ export function resolveSlackGroupToolPolicy( const channelId = params.groupId?.trim(); const groupChannel = params.groupChannel; const channelName = groupChannel?.replace(/^#/, ""); - const normalizedName = normalizeSlackSlug(channelName); + const normalizedName = normalizeHyphenSlug(channelName); const candidates = [ channelId ?? "", channelName ? `#${channelName}` : "", diff --git a/src/config/sessions/group.ts b/src/config/sessions/group.ts index d02726a00..22fbd82f4 100644 --- a/src/config/sessions/group.ts +++ b/src/config/sessions/group.ts @@ -1,17 +1,12 @@ import type { MsgContext } from "../../auto-reply/templating.js"; +import { normalizeHyphenSlug } from "../../shared/string-normalization.js"; import { listDeliverableMessageChannels } from "../../utils/message-channel.js"; import type { GroupKeyResolution } from "./types.js"; const getGroupSurfaces = () => new Set([...listDeliverableMessageChannels(), "webchat"]); function normalizeGroupLabel(raw?: string) { - const trimmed = raw?.trim().toLowerCase() ?? ""; - if (!trimmed) { - return ""; - } - const dashed = trimmed.replace(/\s+/g, "-"); - const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-"); - return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); + return normalizeHyphenSlug(raw); } function shortenGroupId(value?: string) { diff --git a/src/imessage/monitor/runtime.ts b/src/imessage/monitor/runtime.ts index ac2916b56..72066272d 100644 --- a/src/imessage/monitor/runtime.ts +++ b/src/imessage/monitor/runtime.ts @@ -1,4 +1,5 @@ import { createNonExitingRuntime, type RuntimeEnv } from "../../runtime.js"; +import { normalizeStringEntries } from "../../shared/string-normalization.js"; import type { MonitorIMessageOpts } from "./types.js"; export function resolveRuntime(opts: MonitorIMessageOpts): RuntimeEnv { @@ -6,5 +7,5 @@ export function resolveRuntime(opts: MonitorIMessageOpts): RuntimeEnv { } export function normalizeAllowList(list?: Array) { - return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean); + return normalizeStringEntries(list); } diff --git a/src/shared/string-normalization.ts b/src/shared/string-normalization.ts new file mode 100644 index 000000000..9147b1b50 --- /dev/null +++ b/src/shared/string-normalization.ts @@ -0,0 +1,17 @@ +export function normalizeStringEntries(list?: Array) { + return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean); +} + +export function normalizeStringEntriesLower(list?: Array) { + return normalizeStringEntries(list).map((entry) => entry.toLowerCase()); +} + +export function normalizeHyphenSlug(raw?: string | null) { + const trimmed = raw?.trim().toLowerCase() ?? ""; + if (!trimmed) { + return ""; + } + const dashed = trimmed.replace(/\s+/g, "-"); + const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-"); + return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); +} diff --git a/src/slack/monitor/allow-list.ts b/src/slack/monitor/allow-list.ts index 7cae54205..356d95d3d 100644 --- a/src/slack/monitor/allow-list.ts +++ b/src/slack/monitor/allow-list.ts @@ -1,21 +1,20 @@ import type { AllowlistMatch } from "../../channels/allowlist-match.js"; +import { + normalizeHyphenSlug, + normalizeStringEntries, + normalizeStringEntriesLower, +} from "../../shared/string-normalization.js"; export function normalizeSlackSlug(raw?: string) { - const trimmed = raw?.trim().toLowerCase() ?? ""; - if (!trimmed) { - return ""; - } - const dashed = trimmed.replace(/\s+/g, "-"); - const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-"); - return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, ""); + return normalizeHyphenSlug(raw); } export function normalizeAllowList(list?: Array) { - return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean); + return normalizeStringEntries(list); } export function normalizeAllowListLower(list?: Array) { - return normalizeAllowList(list).map((entry) => entry.toLowerCase()); + return normalizeStringEntriesLower(list); } export type SlackAllowListMatch = AllowlistMatch<