fix(discord): align wildcard channel matching
This commit is contained in:
@@ -299,6 +299,7 @@ describe("discord guild/channel resolution", () => {
|
|||||||
expect(general?.allowed).toBe(true);
|
expect(general?.allowed).toBe(true);
|
||||||
expect(general?.requireMention).toBe(false);
|
expect(general?.requireMention).toBe(false);
|
||||||
expect(general?.autoThread).toBeUndefined();
|
expect(general?.autoThread).toBeUndefined();
|
||||||
|
expect(general?.matchSource).toBe("direct");
|
||||||
|
|
||||||
// Unknown channel should use wildcard
|
// Unknown channel should use wildcard
|
||||||
const random = resolveDiscordChannelConfig({
|
const random = resolveDiscordChannelConfig({
|
||||||
@@ -310,6 +311,28 @@ describe("discord guild/channel resolution", () => {
|
|||||||
expect(random?.allowed).toBe(true);
|
expect(random?.allowed).toBe(true);
|
||||||
expect(random?.autoThread).toBe(true);
|
expect(random?.autoThread).toBe(true);
|
||||||
expect(random?.requireMention).toBe(true);
|
expect(random?.requireMention).toBe(true);
|
||||||
|
expect(random?.matchSource).toBe("wildcard");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to wildcard when thread channel and parent are missing", () => {
|
||||||
|
const guildInfo: DiscordGuildEntryResolved = {
|
||||||
|
channels: {
|
||||||
|
"*": { allow: true, requireMention: false },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const thread = resolveDiscordChannelConfigWithFallback({
|
||||||
|
guildInfo,
|
||||||
|
channelId: "thread-123",
|
||||||
|
channelName: "topic",
|
||||||
|
channelSlug: "topic",
|
||||||
|
parentId: "parent-999",
|
||||||
|
parentName: "general",
|
||||||
|
parentSlug: "general",
|
||||||
|
scope: "thread",
|
||||||
|
});
|
||||||
|
expect(thread?.allowed).toBe(true);
|
||||||
|
expect(thread?.matchKey).toBe("*");
|
||||||
|
expect(thread?.matchSource).toBe("wildcard");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { Guild, User } from "@buape/carbon";
|
|||||||
import {
|
import {
|
||||||
buildChannelKeyCandidates,
|
buildChannelKeyCandidates,
|
||||||
resolveChannelEntryMatchWithFallback,
|
resolveChannelEntryMatchWithFallback,
|
||||||
|
type ChannelMatchSource,
|
||||||
} from "../../channels/channel-config.js";
|
} from "../../channels/channel-config.js";
|
||||||
import type { AllowlistMatch } from "../../channels/allowlist-match.js";
|
import type { AllowlistMatch } from "../../channels/allowlist-match.js";
|
||||||
import { formatDiscordUserTag } from "./format.js";
|
import { formatDiscordUserTag } from "./format.js";
|
||||||
@@ -44,7 +45,7 @@ export type DiscordChannelConfigResolved = {
|
|||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
autoThread?: boolean;
|
autoThread?: boolean;
|
||||||
matchKey?: string;
|
matchKey?: string;
|
||||||
matchSource?: "direct" | "parent";
|
matchSource?: ChannelMatchSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function normalizeDiscordAllowList(
|
export function normalizeDiscordAllowList(
|
||||||
@@ -198,13 +199,14 @@ function resolveDiscordChannelEntryMatch(
|
|||||||
entries: channels,
|
entries: channels,
|
||||||
keys,
|
keys,
|
||||||
parentKeys,
|
parentKeys,
|
||||||
|
wildcardKey: "*",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveDiscordChannelConfigEntry(
|
function resolveDiscordChannelConfigEntry(
|
||||||
entry: DiscordChannelEntry,
|
entry: DiscordChannelEntry,
|
||||||
matchKey: string | undefined,
|
matchKey: string | undefined,
|
||||||
matchSource: "direct" | "parent",
|
matchSource: ChannelMatchSource,
|
||||||
): DiscordChannelConfigResolved {
|
): DiscordChannelConfigResolved {
|
||||||
const resolved: DiscordChannelConfigResolved = {
|
const resolved: DiscordChannelConfigResolved = {
|
||||||
allowed: entry.allow !== false,
|
allowed: entry.allow !== false,
|
||||||
@@ -234,15 +236,8 @@ export function resolveDiscordChannelConfig(params: {
|
|||||||
name: channelName,
|
name: channelName,
|
||||||
slug: channelSlug,
|
slug: channelSlug,
|
||||||
});
|
});
|
||||||
if (!match.entry || !match.matchKey) {
|
if (!match.entry || !match.matchKey || !match.matchSource) return { allowed: false };
|
||||||
// Wildcard fallback: apply to all channels if "*" is configured
|
return resolveDiscordChannelConfigEntry(match.entry, match.matchKey, match.matchSource);
|
||||||
const wildcard = channels["*"];
|
|
||||||
if (wildcard) {
|
|
||||||
return resolveDiscordChannelConfigEntry(wildcard, "*", "direct");
|
|
||||||
}
|
|
||||||
return { allowed: false };
|
|
||||||
}
|
|
||||||
return resolveDiscordChannelConfigEntry(match.entry, match.matchKey, "direct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveDiscordChannelConfigWithFallback(params: {
|
export function resolveDiscordChannelConfigWithFallback(params: {
|
||||||
@@ -285,16 +280,7 @@ export function resolveDiscordChannelConfigWithFallback(params: {
|
|||||||
: undefined,
|
: undefined,
|
||||||
);
|
);
|
||||||
if (match.entry && match.matchKey && match.matchSource) {
|
if (match.entry && match.matchKey && match.matchSource) {
|
||||||
return resolveDiscordChannelConfigEntry(
|
return resolveDiscordChannelConfigEntry(match.entry, match.matchKey, match.matchSource);
|
||||||
match.entry,
|
|
||||||
match.matchKey,
|
|
||||||
match.matchSource === "parent" ? "parent" : "direct",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Wildcard fallback: apply to all channels if "*" is configured
|
|
||||||
const wildcard = channels["*"];
|
|
||||||
if (wildcard) {
|
|
||||||
return resolveDiscordChannelConfigEntry(wildcard, "*", "direct");
|
|
||||||
}
|
}
|
||||||
return { allowed: false };
|
return { allowed: false };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user