134 lines
4.3 KiB
TypeScript
134 lines
4.3 KiB
TypeScript
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;
|
|
}
|
|
|
|
export 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;
|
|
}
|
|
|
|
export function toDirectoryEntries(kind: "user" | "group", ids: string[]): ChannelDirectoryEntry[] {
|
|
return ids.map((id) => ({ kind, id }) as const);
|
|
}
|
|
|
|
function normalizeDirectoryIds(params: {
|
|
rawIds: readonly string[];
|
|
normalizeId?: (entry: string) => string | null | undefined;
|
|
}): string[] {
|
|
return params.rawIds
|
|
.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);
|
|
}
|
|
|
|
function collectDirectoryIdsFromEntries(params: {
|
|
entries?: readonly unknown[];
|
|
normalizeId?: (entry: string) => string | null | undefined;
|
|
}): string[] {
|
|
return normalizeDirectoryIds({
|
|
rawIds: (params.entries ?? []).map((entry) => String(entry)),
|
|
normalizeId: params.normalizeId,
|
|
});
|
|
}
|
|
|
|
function collectDirectoryIdsFromMapKeys(params: {
|
|
groups?: Record<string, unknown>;
|
|
normalizeId?: (entry: string) => string | null | undefined;
|
|
}): string[] {
|
|
return normalizeDirectoryIds({
|
|
rawIds: Object.keys(params.groups ?? {}),
|
|
normalizeId: params.normalizeId,
|
|
});
|
|
}
|
|
|
|
function dedupeDirectoryIds(ids: string[]): string[] {
|
|
return Array.from(new Set(ids));
|
|
}
|
|
|
|
export function listDirectoryUserEntriesFromAllowFrom(params: {
|
|
allowFrom?: readonly unknown[];
|
|
query?: string | null;
|
|
limit?: number | null;
|
|
normalizeId?: (entry: string) => string | null | undefined;
|
|
}): ChannelDirectoryEntry[] {
|
|
const ids = dedupeDirectoryIds(
|
|
collectDirectoryIdsFromEntries({
|
|
entries: params.allowFrom,
|
|
normalizeId: params.normalizeId,
|
|
}),
|
|
);
|
|
return toDirectoryEntries("user", applyDirectoryQueryAndLimit(ids, params));
|
|
}
|
|
|
|
export function listDirectoryUserEntriesFromAllowFromAndMapKeys(params: {
|
|
allowFrom?: readonly unknown[];
|
|
map?: Record<string, unknown>;
|
|
query?: string | null;
|
|
limit?: number | null;
|
|
normalizeAllowFromId?: (entry: string) => string | null | undefined;
|
|
normalizeMapKeyId?: (entry: string) => string | null | undefined;
|
|
}): ChannelDirectoryEntry[] {
|
|
const ids = dedupeDirectoryIds([
|
|
...collectDirectoryIdsFromEntries({
|
|
entries: params.allowFrom,
|
|
normalizeId: params.normalizeAllowFromId,
|
|
}),
|
|
...collectDirectoryIdsFromMapKeys({
|
|
groups: params.map,
|
|
normalizeId: params.normalizeMapKeyId,
|
|
}),
|
|
]);
|
|
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 = dedupeDirectoryIds(
|
|
collectDirectoryIdsFromMapKeys({
|
|
groups: params.groups,
|
|
normalizeId: params.normalizeId,
|
|
}),
|
|
);
|
|
return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params));
|
|
}
|
|
|
|
export function listDirectoryGroupEntriesFromMapKeysAndAllowFrom(params: {
|
|
groups?: Record<string, unknown>;
|
|
allowFrom?: readonly unknown[];
|
|
query?: string | null;
|
|
limit?: number | null;
|
|
normalizeMapKeyId?: (entry: string) => string | null | undefined;
|
|
normalizeAllowFromId?: (entry: string) => string | null | undefined;
|
|
}): ChannelDirectoryEntry[] {
|
|
const ids = dedupeDirectoryIds([
|
|
...collectDirectoryIdsFromMapKeys({
|
|
groups: params.groups,
|
|
normalizeId: params.normalizeMapKeyId,
|
|
}),
|
|
...collectDirectoryIdsFromEntries({
|
|
entries: params.allowFrom,
|
|
normalizeId: params.normalizeAllowFromId,
|
|
}),
|
|
]);
|
|
return toDirectoryEntries("group", applyDirectoryQueryAndLimit(ids, params));
|
|
}
|