55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import "server-only";
|
|
|
|
import { PERMS } from "@/lib/permission-slugs";
|
|
import {
|
|
anyCapability,
|
|
type HousekeepingCapabilityContext,
|
|
} from "../../foundation/contracts";
|
|
import { contentQuery } from "./queries/content-queries";
|
|
import type { ContentSearchCandidate } from "./search";
|
|
|
|
type ContentSearchKind = "articles" | "events" | "media" | "help";
|
|
|
|
const SEARCH_ROUTES = {
|
|
articles: [["content.editorial.articles", anyCapability(PERMS.NEWS_VIEW)]],
|
|
events: [["content.engagement.events", anyCapability(PERMS.EVENTS_VIEW)]],
|
|
media: [
|
|
["content.media.photos", anyCapability(PERMS.PAGES_VIEW)],
|
|
["content.media.library", anyCapability(PERMS.PAGES_VIEW)],
|
|
["content.media.banners", anyCapability(PERMS.BANNERS_VIEW)],
|
|
["content.media.ads", anyCapability(PERMS.PAGES_VIEW)],
|
|
],
|
|
help: [
|
|
["content.help.questions", anyCapability(PERMS.PAGES_VIEW)],
|
|
["content.help.email-templates", anyCapability(PERMS.PAGES_VIEW)],
|
|
],
|
|
} as const;
|
|
|
|
export async function loadContentSearchCandidates(
|
|
kind: ContentSearchKind,
|
|
context: HousekeepingCapabilityContext,
|
|
term: string,
|
|
limit: number,
|
|
): Promise<readonly ContentSearchCandidate[]> {
|
|
const candidates: ContentSearchCandidate[] = [];
|
|
for (const [routeId, capability] of SEARCH_ROUTES[kind]) {
|
|
const result = await contentQuery.run(context, {
|
|
routeId,
|
|
list: { search: term, pageSize: limit, offset: 0 },
|
|
});
|
|
if (!result.ok) continue;
|
|
for (const item of result.data.items) {
|
|
if (!item.href) continue;
|
|
candidates.push({
|
|
id: routeId + ":" + item.id,
|
|
title: item.title,
|
|
description: item.description ?? item.status,
|
|
href: item.href,
|
|
capability,
|
|
});
|
|
if (candidates.length >= limit) return candidates;
|
|
}
|
|
}
|
|
return candidates;
|
|
}
|