diff --git a/src/channels/plugins/directory-config.ts b/src/channels/plugins/directory-config.ts index e36e560dbc..eaec8e7b50 100644 --- a/src/channels/plugins/directory-config.ts +++ b/src/channels/plugins/directory-config.ts @@ -34,11 +34,29 @@ function addAllowFromAndDmsIds( } } +function resolveDirectoryQuery(query?: string | null): string { + return query?.trim().toLowerCase() || ""; +} + +function resolveDirectoryLimit(limit?: number | null): number | undefined { + return typeof limit === "number" && limit > 0 ? limit : undefined; +} + +function applyDirectoryQueryAndLimit(ids: string[], params: DirectoryConfigParams): string[] { + const q = resolveDirectoryQuery(params.query); + const limit = resolveDirectoryLimit(params.limit); + const filtered = ids.filter((id) => (q ? id.toLowerCase().includes(q) : true)); + return typeof limit === "number" ? filtered.slice(0, limit) : filtered; +} + +function toDirectoryEntries(kind: "user" | "group", ids: string[]): ChannelDirectoryEntry[] { + return ids.map((id) => ({ kind, id }) as const); +} + export async function listSlackDirectoryPeersFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveSlackAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; const ids = new Set(); addAllowFromAndDmsIds(ids, account.config.allowFrom ?? account.dm?.allowFrom, account.config.dms); @@ -51,7 +69,7 @@ export async function listSlackDirectoryPeersFromConfig( } } - return Array.from(ids) + const normalizedIds = Array.from(ids) .map((raw) => raw.trim()) .filter(Boolean) .map((raw) => { @@ -64,32 +82,26 @@ export async function listSlackDirectoryPeersFromConfig( return normalizeSlackMessagingTarget(target) ?? target.toLowerCase(); }) .filter((id): id is string => Boolean(id)) - .filter((id) => id.startsWith("user:")) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "user", id }) as const); + .filter((id) => id.startsWith("user:")); + return toDirectoryEntries("user", applyDirectoryQueryAndLimit(normalizedIds, params)); } export async function listSlackDirectoryGroupsFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveSlackAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; - return Object.keys(account.config.channels ?? {}) + const ids = Object.keys(account.config.channels ?? {}) .map((raw) => raw.trim()) .filter(Boolean) .map((raw) => normalizeSlackMessagingTarget(raw) ?? raw.toLowerCase()) - .filter((id) => id.startsWith("channel:")) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "group", id }) as const); + .filter((id) => id.startsWith("channel:")); + return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params)); } export async function listDiscordDirectoryPeersFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveDiscordAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; const ids = new Set(); addAllowFromAndDmsIds( @@ -114,7 +126,7 @@ export async function listDiscordDirectoryPeersFromConfig( } } - return Array.from(ids) + const normalizedIds = Array.from(ids) .map((raw) => raw.trim()) .filter(Boolean) .map((raw) => { @@ -125,17 +137,14 @@ export async function listDiscordDirectoryPeersFromConfig( } return `user:${cleaned}`; }) - .filter((id): id is string => Boolean(id)) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "user", id }) as const); + .filter((id): id is string => Boolean(id)); + return toDirectoryEntries("user", applyDirectoryQueryAndLimit(normalizedIds, params)); } export async function listDiscordDirectoryGroupsFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveDiscordAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; const ids = new Set(); for (const guild of Object.values(account.config.guilds ?? {})) { for (const channelId of Object.keys(guild.channels ?? {})) { @@ -146,7 +155,7 @@ export async function listDiscordDirectoryGroupsFromConfig( } } - return Array.from(ids) + const normalizedIds = Array.from(ids) .map((raw) => raw.trim()) .filter(Boolean) .map((raw) => { @@ -157,22 +166,19 @@ export async function listDiscordDirectoryGroupsFromConfig( } return `channel:${cleaned}`; }) - .filter((id): id is string => Boolean(id)) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "group", id }) as const); + .filter((id): id is string => Boolean(id)); + return toDirectoryEntries("group", applyDirectoryQueryAndLimit(normalizedIds, params)); } export async function listTelegramDirectoryPeersFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveTelegramAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; const raw = [ ...(account.config.allowFrom ?? []).map((entry) => String(entry)), ...Object.keys(account.config.dms ?? {}), ]; - return Array.from( + const ids = Array.from( new Set( raw .map((entry) => entry.trim()) @@ -191,50 +197,39 @@ export async function listTelegramDirectoryPeersFromConfig( const withAt = trimmed.startsWith("@") ? trimmed : `@${trimmed}`; return withAt; }) - .filter((id): id is string => Boolean(id)) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "user", id }) as const); + .filter((id): id is string => Boolean(id)); + return toDirectoryEntries("user", applyDirectoryQueryAndLimit(ids, params)); } export async function listTelegramDirectoryGroupsFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveTelegramAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; - return Object.keys(account.config.groups ?? {}) + const ids = Object.keys(account.config.groups ?? {}) .map((id) => id.trim()) - .filter((id) => Boolean(id) && id !== "*") - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "group", id }) as const); + .filter((id) => Boolean(id) && id !== "*"); + return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params)); } export async function listWhatsAppDirectoryPeersFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveWhatsAppAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; - return (account.allowFrom ?? []) + const ids = (account.allowFrom ?? []) .map((entry) => String(entry).trim()) .filter((entry) => Boolean(entry) && entry !== "*") .map((entry) => normalizeWhatsAppTarget(entry) ?? "") .filter(Boolean) - .filter((id) => !isWhatsAppGroupJid(id)) - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "user", id }) as const); + .filter((id) => !isWhatsAppGroupJid(id)); + return toDirectoryEntries("user", applyDirectoryQueryAndLimit(ids, params)); } export async function listWhatsAppDirectoryGroupsFromConfig( params: DirectoryConfigParams, ): Promise { const account = resolveWhatsAppAccount({ cfg: params.cfg, accountId: params.accountId }); - const q = params.query?.trim().toLowerCase() || ""; - return Object.keys(account.groups ?? {}) + const ids = Object.keys(account.groups ?? {}) .map((id) => id.trim()) - .filter((id) => Boolean(id) && id !== "*") - .filter((id) => (q ? id.toLowerCase().includes(q) : true)) - .slice(0, params.limit && params.limit > 0 ? params.limit : undefined) - .map((id) => ({ kind: "group", id }) as const); + .filter((id) => Boolean(id) && id !== "*"); + return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params)); }