refactor(channels): centralize match metadata
This commit is contained in:
@@ -16,6 +16,8 @@ export type AllowlistMatch<TSource extends string = AllowlistMatchSource> = {
|
||||
matchSource?: TSource;
|
||||
};
|
||||
|
||||
export function formatAllowlistMatchMeta(match?: AllowlistMatch | null): string {
|
||||
export function formatAllowlistMatchMeta(
|
||||
match?: { matchKey?: string; matchSource?: string } | null,
|
||||
): string {
|
||||
return `matchKey=${match?.matchKey ?? "none"} matchSource=${match?.matchSource ?? "none"}`;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
resolveChannelEntryMatch,
|
||||
resolveChannelEntryMatchWithFallback,
|
||||
resolveNestedAllowlistDecision,
|
||||
applyChannelMatchMeta,
|
||||
resolveChannelMatchConfig,
|
||||
} from "./channel-config.js";
|
||||
|
||||
describe("buildChannelKeyCandidates", () => {
|
||||
@@ -90,6 +92,33 @@ describe("resolveChannelEntryMatchWithFallback", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("applyChannelMatchMeta", () => {
|
||||
it("copies match metadata onto resolved configs", () => {
|
||||
const resolved = applyChannelMatchMeta(
|
||||
{ allowed: true },
|
||||
{ matchKey: "general", matchSource: "direct" },
|
||||
);
|
||||
expect(resolved.matchKey).toBe("general");
|
||||
expect(resolved.matchSource).toBe("direct");
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveChannelMatchConfig", () => {
|
||||
it("returns null when no entry is matched", () => {
|
||||
const resolved = resolveChannelMatchConfig({ matchKey: "x" }, () => ({ allowed: true }));
|
||||
expect(resolved).toBeNull();
|
||||
});
|
||||
|
||||
it("resolves entry and applies match metadata", () => {
|
||||
const resolved = resolveChannelMatchConfig(
|
||||
{ entry: { allow: true }, matchKey: "*", matchSource: "wildcard" },
|
||||
() => ({ allowed: true }),
|
||||
);
|
||||
expect(resolved?.matchKey).toBe("*");
|
||||
expect(resolved?.matchSource).toBe("wildcard");
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveNestedAllowlistDecision", () => {
|
||||
it("allows when outer allowlist is disabled", () => {
|
||||
expect(
|
||||
|
||||
@@ -11,6 +11,24 @@ export type ChannelEntryMatch<T> = {
|
||||
matchSource?: ChannelMatchSource;
|
||||
};
|
||||
|
||||
export function applyChannelMatchMeta<
|
||||
TResult extends { matchKey?: string; matchSource?: ChannelMatchSource },
|
||||
>(result: TResult, match: ChannelEntryMatch<unknown>): TResult {
|
||||
if (match.matchKey && match.matchSource) {
|
||||
result.matchKey = match.matchKey;
|
||||
result.matchSource = match.matchSource;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function resolveChannelMatchConfig<
|
||||
TEntry,
|
||||
TResult extends { matchKey?: string; matchSource?: ChannelMatchSource },
|
||||
>(match: ChannelEntryMatch<TEntry>, resolveEntry: (entry: TEntry) => TResult): TResult | null {
|
||||
if (!match.entry) return null;
|
||||
return applyChannelMatchMeta(resolveEntry(match.entry), match);
|
||||
}
|
||||
|
||||
export function normalizeChannelSlug(value: string): string {
|
||||
return value
|
||||
.trim()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
export type { ChannelEntryMatch, ChannelMatchSource } from "../channel-config.js";
|
||||
export {
|
||||
applyChannelMatchMeta,
|
||||
buildChannelKeyCandidates,
|
||||
normalizeChannelSlug,
|
||||
resolveChannelEntryMatch,
|
||||
resolveChannelEntryMatchWithFallback,
|
||||
resolveChannelMatchConfig,
|
||||
resolveNestedAllowlistDecision,
|
||||
} from "../channel-config.js";
|
||||
|
||||
@@ -60,10 +60,12 @@ export {
|
||||
listWhatsAppDirectoryPeersFromConfig,
|
||||
} from "./directory-config.js";
|
||||
export {
|
||||
applyChannelMatchMeta,
|
||||
buildChannelKeyCandidates,
|
||||
normalizeChannelSlug,
|
||||
resolveChannelEntryMatch,
|
||||
resolveChannelEntryMatchWithFallback,
|
||||
resolveChannelMatchConfig,
|
||||
resolveNestedAllowlistDecision,
|
||||
type ChannelEntryMatch,
|
||||
type ChannelMatchSource,
|
||||
|
||||
Reference in New Issue
Block a user