refactor: unify directory config entry extraction

This commit is contained in:
Peter Steinberger
2026-03-07 19:57:22 +00:00
parent b0ac284dae
commit b9e7521463
6 changed files with 129 additions and 35 deletions

View File

@@ -0,0 +1,39 @@
import { describe, expect, it } from "vitest";
import {
listDirectoryGroupEntriesFromMapKeys,
listDirectoryUserEntriesFromAllowFrom,
} from "./directory-config-helpers.js";
describe("listDirectoryUserEntriesFromAllowFrom", () => {
it("normalizes, deduplicates, filters, and limits user ids", () => {
const entries = listDirectoryUserEntriesFromAllowFrom({
allowFrom: ["", "*", " user:Alice ", "user:alice", "user:Bob", "user:Carla"],
normalizeId: (entry) => entry.replace(/^user:/i, "").toLowerCase(),
query: "a",
limit: 2,
});
expect(entries).toEqual([
{ kind: "user", id: "alice" },
{ kind: "user", id: "carla" },
]);
});
});
describe("listDirectoryGroupEntriesFromMapKeys", () => {
it("extracts normalized group ids from map keys", () => {
const entries = listDirectoryGroupEntriesFromMapKeys({
groups: {
"*": {},
" Space/A ": {},
"space/b": {},
},
normalizeId: (entry) => entry.toLowerCase().replace(/\s+/g, ""),
});
expect(entries).toEqual([
{ kind: "group", id: "space/a" },
{ kind: "group", id: "space/b" },
]);
});
});

View File

@@ -0,0 +1,65 @@
import type { ChannelDirectoryEntry } from "./types.js";
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: { query?: string | null; limit?: number | null },
): 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 function listDirectoryUserEntriesFromAllowFrom(params: {
allowFrom?: readonly unknown[];
query?: string | null;
limit?: number | null;
normalizeId?: (entry: string) => string | null | undefined;
}): ChannelDirectoryEntry[] {
const ids = Array.from(
new Set(
(params.allowFrom ?? [])
.map((entry) => String(entry).trim())
.filter((entry) => Boolean(entry) && entry !== "*")
.map((entry) => {
const normalized = params.normalizeId ? params.normalizeId(entry) : entry;
return typeof normalized === "string" ? normalized.trim() : "";
})
.filter(Boolean),
),
);
return toDirectoryEntries("user", applyDirectoryQueryAndLimit(ids, params));
}
export function listDirectoryGroupEntriesFromMapKeys(params: {
groups?: Record<string, unknown>;
query?: string | null;
limit?: number | null;
normalizeId?: (entry: string) => string | null | undefined;
}): ChannelDirectoryEntry[] {
const ids = Array.from(
new Set(
Object.keys(params.groups ?? {})
.map((entry) => entry.trim())
.filter((entry) => Boolean(entry) && entry !== "*")
.map((entry) => {
const normalized = params.normalizeId ? params.normalizeId(entry) : entry;
return typeof normalized === "string" ? normalized.trim() : "";
})
.filter(Boolean),
),
);
return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params));
}