Core: Support passing tag to search client/server as string array

This commit is contained in:
Fuma Nama
2025-06-27 22:46:54 +08:00
parent a30fb62c78
commit 84918b8d1d
7 changed files with 41 additions and 27 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-core': patch
---
Support passing `tag` to search client/server as string array
+3 -3
View File
@@ -9,9 +9,9 @@ export interface FetchOptions {
api?: string;
/**
* Filter results with specific tag.
* Filter results with specific tag(s).
*/
tag?: string;
tag?: string | string[];
/**
* Filter by locale
@@ -28,7 +28,7 @@ export async function fetchDocs(
const params = new URLSearchParams();
params.set('query', query);
if (locale) params.set('locale', locale);
if (tag) params.set('tag', tag);
if (tag) params.set('tag', Array.isArray(tag) ? tag.join(',') : tag);
const key = `${api}?${params}`;
const cached = cache.get(key);
+2 -2
View File
@@ -18,9 +18,9 @@ export interface StaticOptions {
initOrama?: (locale?: string) => AnyOrama | Promise<AnyOrama>;
/**
* Filter results with specific tag.
* Filter results with specific tag(s).
*/
tag?: string;
tag?: string | string[];
/**
* Filter by locale (unsupported at the moment)
+10 -7
View File
@@ -12,8 +12,7 @@ export const advancedSchema = {
content: 'string',
page_id: 'string',
type: 'string',
keywords: 'string',
tag: 'string',
tags: 'enum[]',
url: 'string',
} as const;
@@ -36,6 +35,11 @@ export async function createDB({
const mapTo: PartialSchemaDeep<AdvancedDocument>[] = [];
items.forEach((page) => {
const tags = Array.isArray(page.tag)
? page.tag
: page.tag
? [page.tag]
: [];
const data = page.structuredData;
let id = 0;
@@ -44,8 +48,7 @@ export async function createDB({
page_id: page.id,
type: 'page',
content: page.title,
keywords: page.keywords,
tag: page.tag,
tags,
url: page.url,
});
@@ -53,7 +56,7 @@ export async function createDB({
mapTo.push({
id: `${page.id}-${(id++).toString()}`,
page_id: page.id,
tag: page.tag,
tags,
type: 'text',
url: page.url,
content: page.description,
@@ -65,7 +68,7 @@ export async function createDB({
id: `${page.id}-${(id++).toString()}`,
page_id: page.id,
type: 'heading',
tag: page.tag,
tags,
url: `${page.url}#${heading.id}`,
content: heading.content,
});
@@ -75,7 +78,7 @@ export async function createDB({
mapTo.push({
id: `${page.id}-${(id++).toString()}`,
page_id: page.id,
tag: page.tag,
tags,
type: 'text',
url: content.heading ? `${page.url}#${content.heading}` : page.url,
content: content.content,
@@ -15,7 +15,7 @@ export function createEndpoint(server: SearchServer): SearchAPI {
return Response.json(
await search(query, {
tag: url.searchParams.get('tag') ?? undefined,
tag: url.searchParams.get('tag')?.split(',') ?? undefined,
locale: url.searchParams.get('locale') ?? undefined,
}),
);
@@ -9,14 +9,19 @@ import type { SortedResult } from '@/server';
export async function searchAdvanced(
db: Orama<typeof advancedSchema>,
query: string,
tag: string | undefined,
tag: string | string[] = [],
extraParams: Partial<
SearchParams<Orama<typeof advancedSchema>, AdvancedDocument>
> = {},
): Promise<SortedResult[]> {
let params: SearchParams<typeof db, AdvancedDocument> = {
if (typeof tag === 'string') tag = [tag];
let params = {
...extraParams,
where: removeUndefined({
tag,
tags: {
containsAll: tag,
},
...extraParams.where,
}),
groupBy: {
@@ -24,17 +29,14 @@ export async function searchAdvanced(
maxResult: 8,
...extraParams.groupBy,
},
};
} as SearchParams<typeof db, AdvancedDocument>;
if (query.length > 0) {
params = {
...params,
term: query,
properties: ['content', 'keywords'],
...extraParams,
where: params.where,
groupBy: params.groupBy,
};
properties: ['content'],
} as SearchParams<typeof db, AdvancedDocument>;
}
const result = await search(db, params);
+9 -5
View File
@@ -1,9 +1,9 @@
import {
type Orama,
type SearchParams,
save,
create,
type Orama,
type RawData,
save,
type SearchParams,
} from '@orama/orama';
import type { StructuredData } from '@/mdx-plugins/remark-structure';
import type { SortedResult } from '@/server/types';
@@ -31,7 +31,7 @@ export type ExportedData =
export interface SearchServer {
search: (
query: string,
options?: { locale?: string; tag?: string },
options?: { locale?: string; tag?: string | string[] },
) => Promise<SortedResult[]>;
/**
@@ -125,12 +125,16 @@ export interface AdvancedIndex {
title: string;
description?: string;
/**
* @deprecated No longer used
*/
keywords?: string;
/**
* Required if tag filter is enabled
*/
tag?: string;
tag?: string | string[];
/**
* preprocess mdx content with `structure`
*/