fix(channels): clean up discord resolve typing

This commit is contained in:
Peter Steinberger
2026-01-18 00:59:23 +00:00
parent 075ff675ac
commit 4f0771f67b
4 changed files with 35 additions and 25 deletions

View File

@@ -1,12 +1,16 @@
import type { ClawdbotConfig } from "../../../config/config.js";
import type { DmPolicy } from "../../../config/types.js";
import type { DiscordGuildEntry } from "../../../config/types.discord.js";
import {
listDiscordAccountIds,
resolveDefaultDiscordAccountId,
resolveDiscordAccount,
} from "../../../discord/accounts.js";
import { normalizeDiscordSlug } from "../../../discord/monitor/allow-list.js";
import { resolveDiscordChannelAllowlist } from "../../../discord/resolve-channels.js";
import {
resolveDiscordChannelAllowlist,
type DiscordChannelResolution,
} from "../../../discord/resolve-channels.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
import { formatDocsLink } from "../../../terminal/links.js";
import type { WizardPrompter } from "../../../wizard/prompts.js";
@@ -99,14 +103,12 @@ function setDiscordGuildChannelAllowlist(
accountId === DEFAULT_ACCOUNT_ID
? (cfg.channels?.discord?.guilds ?? {})
: (cfg.channels?.discord?.accounts?.[accountId]?.guilds ?? {});
const guilds: Record<string, { channels?: Record<string, { allow: boolean }> }> = {
...baseGuilds,
};
const guilds: Record<string, DiscordGuildEntry> = { ...baseGuilds };
for (const entry of entries) {
const guildKey = entry.guildKey || "*";
const existing = guilds[guildKey] ?? {};
if (entry.channelKey) {
const channels = { ...(existing.channels ?? {}) };
const channels = { ...existing.channels };
channels[entry.channelKey] = { allow: true };
guilds[guildKey] = { ...existing, channels };
} else {
@@ -298,7 +300,10 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = {
cfg: next,
accountId: discordAccountId,
});
let resolved = accessConfig.entries.map((input) => ({ input, resolved: false }));
let resolved: DiscordChannelResolution[] = accessConfig.entries.map((input) => ({
input,
resolved: false,
}));
if (accountWithTokens.token && accessConfig.entries.length > 0) {
try {
resolved = await resolveDiscordChannelAllowlist({

View File

@@ -156,7 +156,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
token,
entries: entries.map((entry) => entry.input),
});
const nextGuilds = { ...(guildEntries ?? {}) };
const nextGuilds = { ...guildEntries };
const mapping: string[] = [];
const unresolved: string[] = [];
for (const entry of resolved) {
@@ -173,10 +173,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
: `${entry.input}${entry.guildId}`,
);
const existing = nextGuilds[entry.guildId] ?? {};
const mergedChannels = {
...(sourceGuild.channels ?? {}),
...(existing.channels ?? {}),
};
const mergedChannels = { ...sourceGuild.channels, ...existing.channels };
const mergedGuild = { ...sourceGuild, ...existing, channels: mergedChannels };
nextGuilds[entry.guildId] = mergedGuild;
if (source.channelKey && entry.channelId) {
@@ -188,7 +185,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
...mergedChannels,
[entry.channelId]: {
...sourceChannel,
...(mergedChannels?.[entry.channelId] ?? {}),
...mergedChannels?.[entry.channelId],
},
},
};
@@ -266,7 +263,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
.filter((entry) => !entry.resolved)
.map((entry) => entry.input);
const nextGuilds = { ...(guildEntries ?? {}) };
const nextGuilds = { ...guildEntries };
for (const [guildKey, guildConfig] of Object.entries(guildEntries ?? {})) {
if (!guildConfig || typeof guildConfig !== "object") continue;
const nextGuild = { ...guildConfig } as Record<string, unknown>;

View File

@@ -100,13 +100,19 @@ async function listGuildChannels(
)) as RESTGetAPIGuildChannelsResult;
return raw
.filter((channel) => Boolean(channel.id) && "name" in channel)
.map((channel) => ({
id: channel.id,
name: "name" in channel ? channel.name ?? "" : "",
guildId,
type: channel.type,
archived: "thread_metadata" in channel ? channel.thread_metadata?.archived : undefined,
}))
.map((channel) => {
const archived =
"thread_metadata" in channel
? (channel as { thread_metadata?: { archived?: boolean } }).thread_metadata?.archived
: undefined;
return {
id: channel.id,
name: "name" in channel ? channel.name ?? "" : "",
guildId,
type: channel.type,
archived,
};
})
.filter((channel) => Boolean(channel.name));
}
@@ -231,19 +237,20 @@ export async function resolveDiscordChannelAllowlist(params: {
: parsed.guild
? resolveGuildByName(guilds, parsed.guild)
: undefined;
if (!guild || !parsed.channel) {
const channelQuery = parsed.channel?.trim();
if (!guild || !channelQuery) {
results.push({
input,
resolved: false,
guildId: parsed.guildId,
guildName: parsed.guild,
channelName: parsed.channel,
channelName: channelQuery ?? parsed.channel,
});
continue;
}
const channels = await getChannels(guild.id);
const matches = channels.filter(
(channel) => normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(parsed.channel),
(channel) => normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(channelQuery),
);
const match = preferActiveMatch(matches);
if (match) {

View File

@@ -127,10 +127,11 @@ export async function resolveDiscordUserAllowlist(params: {
continue;
}
const guildName = parsed.guildName?.trim();
const guildList = parsed.guildId
? guilds.filter((g) => g.id === parsed.guildId)
: parsed.guildName
? guilds.filter((g) => g.slug === normalizeDiscordSlug(parsed.guildName))
: guildName
? guilds.filter((g) => g.slug === normalizeDiscordSlug(guildName))
: guilds;
let best: { member: DiscordMember; guild: DiscordGuildSummary; score: number } | null = null;