import type { ProviderName } from "../../providers"; /** * Search query parsing, pagination, and filters (C8). * * `/api/search` returned `{ hasMore: false, offset: 0, total: results.length }` * with all three values hardcoded. That was not merely unimplemented — it was * actively wrong: the scanner truncates at `limit`, so a query with more matches * than the limit reported `hasMore: false` and `total` equal to the truncated * count. A client had no way to learn that results were missing, let alone * fetch them. * * The scanner also already computes a relevance `score` and match `snippets` * per result, and the endpoint discarded both — so results arrived in an * unexplained order with no indication of *why* anything matched. */ export declare const DEFAULT_SEARCH_LIMIT = 50; export declare const MAX_SEARCH_LIMIT = 200; export declare const MAX_QUERY_LENGTH = 256; export interface SearchFilters { provider?: ProviderName; projectPath?: string; branch?: string; /** Inclusive lower bound on last activity, epoch ms. */ since?: number; /** Inclusive upper bound on last activity, epoch ms. */ until?: number; } export interface ParsedSearchQuery { q: string; limit: number; offset: number; filters: SearchFilters; } export declare class SearchQueryError extends Error { readonly code: string; constructor(message: string, code: string); } /** * Parse and validate search parameters. * * Rejects rather than silently clamping an invalid query, so a client that * mistypes a filter learns about it instead of receiving plausible-looking * results for a query it did not mean. `limit` is the exception: it is clamped, * because an over-large limit is a resource question rather than a * misunderstanding, and failing a search over it would be unhelpful. */ export declare function parseSearchQuery(params: URLSearchParams): ParsedSearchQuery; /** A search result as returned to clients, after adaptation. */ export interface AdaptedResult { projectPath?: string; branch?: string; provider?: string; lastActivity?: string | number | null; } /** * Apply the filters the scanner cannot express itself. * * The scanner's SearchOptions supports `provider` but not project, branch, or * date bounds, so those are applied here. Filtering after the fact means the * scanner's own limit must be raised before slicing — see `handleSearch` — or * a filter would silently drop results that a later page should have contained. */ export declare function applyFilters(results: T[], filters: SearchFilters): T[]; export interface Page { items: T[]; total: number; offset: number; hasMore: boolean; } /** * Slice a filtered result set into a page. * * `total` is the count AFTER filtering and BEFORE slicing, and `hasMore` is * derived from it — the two values the previous implementation hardcoded to * `results.length` and `false`. */ export declare function paginate(results: T[], offset: number, limit: number): Page; //# sourceMappingURL=searchQuery.d.ts.map