Search query string.
Array of parsed tokens.
export function parseQuerySyntax(query: string): QuerySyntaxToken[] {
const tokens: QuerySyntaxToken[] = [];
const parts = query.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
for (const part of parts) {
// Remove quotes if present
const cleaned = part.replaceAll(/(?:^")|(?:"$)/g, "");
// Check for field:value pattern
const fieldPattern = /^(genre|format|year|tag):(.+)$/i;
const fieldMatch = fieldPattern.exec(cleaned);
if (fieldMatch) {
const [, field, value] = fieldMatch;
// Handle year range (e.g., 2020-2023)
if (field.toLowerCase() === "year" && value.includes("-")) {
const [min, max] = value.split("-").map((v) => v.trim());
tokens.push({
type: "field",
field: "year",
value: `${min}-${max}`,
});
} else {
tokens.push({
type: "field",
field: field.toLowerCase(),
value,
});
}
} else {
// Plain text for fuzzy search
tokens.push({
type: "text",
value: cleaned,
});
}
}
return tokens;
}
Parses search query into tokens for field-specific filtering.
Supported syntax:
genre:action- Filter by genreformat:manga- Filter by formatyear:2020-2023- Filter by year rangetag:isekai- Filter by tag