feat: unify API options structure and enhance lookup handling across collections

This commit is contained in:
2026-05-17 14:53:52 +00:00
parent f332c707b7
commit bd8d413850
10 changed files with 58 additions and 112 deletions
+23 -39
View File
@@ -159,45 +159,30 @@
try {
// Load navigation
const [headerEntries, footerEntries] = await Promise.all([
getCachedEntries<"navigation">(
"navigation",
{ type: "header", language: lang },
"sort",
1,
undefined,
undefined,
undefined,
NAVIGATION_CONTENT_LOOKUP
),
getCachedEntries<"navigation">(
"navigation",
{ type: "footer", language: lang },
"sort",
1,
undefined,
undefined,
undefined,
NAVIGATION_CONTENT_LOOKUP
),
getCachedEntries<"navigation">("navigation", {
filter: { type: "header", language: lang },
sort: "sort",
limit: 1,
lookup: NAVIGATION_CONTENT_LOOKUP
}),
getCachedEntries<"navigation">("navigation", {
filter: { type: "footer", language: lang },
sort: "sort",
limit: 1,
lookup: NAVIGATION_CONTENT_LOOKUP
}),
])
headerNav = headerEntries[0] || null
footerNav = footerEntries[0] || null
// Load content for current path. Limit 1 so SSR tracks content:<id> instead of content:*.
const contentEntries = await getCachedEntries<"content">(
"content",
{
lang,
path: routePath,
active: true,
},
"sort",
1,
undefined,
undefined,
{ aggregate: "comments:contentId:count" },
CONTENT_MEDIA_LOOKUP
)
const contentEntries = await getCachedEntries<"content">("content", {
filter: { lang, path: routePath, active: true },
sort: "sort",
limit: 1,
aggregate: "comments:contentId:count",
lookup: CONTENT_MEDIA_LOOKUP
})
if (contentEntries.length > 0) {
contentEntry = contentEntries[0]
@@ -208,11 +193,10 @@
}
try {
comments = await getCachedEntries(
"comments",
{ active: true, contentId: contentEntry.id as string },
"sort"
)
comments = await getCachedEntries("comments", {
filter: { active: true, contentId: contentEntry.id as string },
sort: "sort"
})
} catch (e) {
console.error("Failed to load comments", e)
comments = []
+9 -35
View File
@@ -149,63 +149,37 @@ type EntryTypeSwitch<T extends string> = T extends "medialib"
export async function getDBEntries<T extends CollectionNameT>(
collectionName: T,
filter?: MongoFilter,
sort: string = "sort",
limit?: number,
offset?: number,
projection?: string,
params?: Record<string, string>,
lookup?: string
options?: ApiOptions
): Promise<EntryTypeSwitch<T>[]> {
const c = await api<EntryTypeSwitch<T>[]>(collectionName, {
filter,
sort,
limit,
offset,
projection,
params,
lookup,
})
const c = await api<EntryTypeSwitch<T>[]>(collectionName, options)
return c.data
}
export async function getCachedEntries<T extends CollectionNameT>(
collectionName: T,
filter?: MongoFilter,
sort: string = "sort",
limit?: number,
offset?: number,
projection?: string,
params?: Record<string, string>,
lookup?: string
options?: ApiOptions
): Promise<EntryTypeSwitch<T>[]> {
const filterStr = obj2str({ collectionName, filter, sort, limit, offset, projection, params, lookup })
const filterStr = obj2str({ collectionName, options })
if (cache[filterStr] && cache[filterStr].expire >= Date.now()) {
return cache[filterStr].data as EntryTypeSwitch<T>[]
}
const entries = await getDBEntries<T>(collectionName, filter, sort, limit, offset, projection, params, lookup)
const entries = await getDBEntries<T>(collectionName, options)
cache[filterStr] = { expire: Date.now() + CACHE_TTL, data: entries }
return entries
}
export async function getDBEntry<T extends CollectionNameT>(
collectionName: T,
filter: MongoFilter,
projection?: string,
params?: Record<string, string>,
lookup?: string
options?: ApiOptions
): Promise<EntryTypeSwitch<T> | undefined> {
return (await getDBEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params, lookup))?.[0]
return (await getDBEntries<T>(collectionName, { ...options, limit: 1 }))?.[0]
}
export async function getCachedEntry<T extends CollectionNameT>(
collectionName: T,
filter: MongoFilter,
projection?: string,
params?: Record<string, string>,
lookup?: string
options?: ApiOptions
): Promise<EntryTypeSwitch<T> | undefined> {
return (await getCachedEntries<T>(collectionName, filter, "_id", 1, undefined, projection, params, lookup))?.[0]
return (await getCachedEntries<T>(collectionName, { ...options, limit: 1 }))?.[0]
}
export async function postDBEntry<T extends CollectionNameT>(
+1 -1
View File
@@ -242,7 +242,7 @@ function cloneEntry<T>(entry: T): T {
}
function applyAggregate(entry: Record<string, unknown>, options?: ApiOptions): Record<string, unknown> {
const rawAggregate = options?.params?.aggregate
const rawAggregate = options?.aggregate || options?.params?.aggregate
if (!rawAggregate) return entry
const aggregates = Array.isArray(rawAggregate)