fix: compact discord allowlist resolution logs

This commit is contained in:
Peter Steinberger
2026-04-12 19:08:51 +01:00
parent 067f27f6a2
commit c4412c6b0c
2 changed files with 109 additions and 6 deletions

View File

@@ -87,4 +87,64 @@ describe("resolveDiscordAllowlistConfig", () => {
);
expect(logs).toContain("discord users resolved: 387→Peter (id:387)");
});
it("groups resolved discord channel aliases under one target line", async () => {
vi.spyOn(resolveChannelsModule, "resolveDiscordChannelAllowlist").mockResolvedValueOnce([
{
input: "1456350064065904867/1464953333713473657",
resolved: true,
guildId: "1456350064065904867",
guildName: "Friends of the Crustacean 🦞🤝",
channelId: "1464953333713473657",
channelName: "dev",
},
{
input: "1456350064065904867/1456744319972282449",
resolved: true,
guildId: "1456350064065904867",
guildName: "Friends of the Crustacean 🦞🤝",
channelId: "1456744319972282449",
channelName: "maintainers",
},
{
input: "friends-of-the-crustacean/1464953333713473657",
resolved: true,
guildId: "1456350064065904867",
guildName: "Friends of the Crustacean 🦞🤝",
channelId: "1464953333713473657",
channelName: "dev",
},
]);
const runtime = createNonExitingTypedRuntimeEnv<RuntimeEnv>();
await resolveDiscordAllowlistConfig({
token: "token",
allowFrom: [],
guildEntries: {
"1456350064065904867": {
channels: {
"1464953333713473657": {},
"1456744319972282449": {},
},
},
"friends-of-the-crustacean": {
channels: {
"1464953333713473657": {},
},
},
},
fetcher: vi.fn() as unknown as typeof fetch,
runtime,
});
const logs = (runtime.log as ReturnType<typeof vi.fn>).mock.calls
.map(([line]) => String(line))
.join("\n");
expect(logs.match(/1456350064065904867\/1464953333713473657/g)?.length).toBe(1);
expect(logs).toContain("aliases:friends-of-the-crustacean/1464953333713473657");
expect(logs).toContain(
"1456350064065904867/1456744319972282449 (guild:Friends of the Crustacean 🦞🤝; channel:maintainers)",
);
});
});

View File

@@ -22,6 +22,13 @@ type DiscordChannelLogEntry = {
channelName?: string;
note?: string;
};
type DiscordChannelResolvedGroup = {
target: string;
aliases: string[];
guildName?: string;
channelName?: string;
note?: string;
};
type DiscordUserLogEntry = {
input: string;
id?: string;
@@ -44,13 +51,24 @@ function formatResolvedBase(input: string, target: string | undefined): string {
return input === target ? input : `${input}${target}`;
}
function formatDiscordChannelResolved(entry: DiscordChannelLogEntry): string {
const target = entry.channelId ? `${entry.guildId}/${entry.channelId}` : entry.guildId;
const base = formatResolvedBase(entry.input, target);
return formatResolutionLogDetails(base, [
function formatAliasSummary(aliases: string[]): string | undefined {
if (aliases.length === 0) {
return undefined;
}
const preview = aliases.slice(0, 3).join(", ");
if (aliases.length <= 3) {
return preview;
}
return `${preview}, +${aliases.length - 3} more`;
}
function formatDiscordChannelResolvedGroup(entry: DiscordChannelResolvedGroup): string {
const aliasSummary = formatAliasSummary(entry.aliases);
return formatResolutionLogDetails(entry.target, [
entry.guildName ? `guild:${entry.guildName}` : undefined,
entry.channelName ? `channel:${entry.channelName}` : undefined,
entry.note,
aliasSummary ? `aliases:${aliasSummary}` : undefined,
]);
}
@@ -156,7 +174,7 @@ async function resolveGuildEntriesByChannelAllowlist(params: {
});
const sourceByInput = new Map(entries.map((entry) => [entry.input, entry]));
const nextGuilds = { ...params.guildEntries };
const mapping: string[] = [];
const mappingByTarget = new Map<string, DiscordChannelResolvedGroup>();
const unresolved: string[] = [];
for (const entry of resolved) {
const source = sourceByInput.get(entry.input);
@@ -168,7 +186,29 @@ async function resolveGuildEntriesByChannelAllowlist(params: {
unresolved.push(formatDiscordChannelUnresolved(entry));
continue;
}
mapping.push(formatDiscordChannelResolved(entry));
const target = entry.channelId ? `${entry.guildId}/${entry.channelId}` : entry.guildId;
const existingGroup =
mappingByTarget.get(target) ??
({
target,
aliases: [],
guildName: entry.guildName,
channelName: entry.channelName,
note: entry.note,
} satisfies DiscordChannelResolvedGroup);
if (entry.input !== target && !existingGroup.aliases.includes(entry.input)) {
existingGroup.aliases.push(entry.input);
}
if (!existingGroup.guildName && entry.guildName) {
existingGroup.guildName = entry.guildName;
}
if (!existingGroup.channelName && entry.channelName) {
existingGroup.channelName = entry.channelName;
}
if (!existingGroup.note && entry.note) {
existingGroup.note = entry.note;
}
mappingByTarget.set(target, existingGroup);
const existing = nextGuilds[entry.guildId] ?? {};
const mergedChannels = {
...sourceGuild.channels,
@@ -197,6 +237,9 @@ async function resolveGuildEntriesByChannelAllowlist(params: {
}
}
}
const mapping = [...mappingByTarget.values()].map((group) =>
formatDiscordChannelResolvedGroup(group),
);
summarizeMapping("discord channels", mapping, unresolved, params.runtime);
return nextGuilds;
} catch (err) {